<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="description" content="生产线实时故障监测与数据分析平台">
    <title>生产线智能检测系统</title>
    <!-- 外部资源引入 -->
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
    <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
    
    <!-- Tailwind 配置：风格（简洁、高对比度、柔和色彩） -->
    <script>
        tailwind.config = {
            darkMode: 'class',
            theme: {
                extend: {
                    colors: {
                        primary: '#007AFF',    // 系统蓝（强调色）
                        secondary: '#34C759',  // 成功绿
                        alert: '#FF3B30',      // 警告红
                        info: '#5AC8FA',       // 信息蓝
                        neutral: {
                            100: '#F5F5F7',  // 浅灰背景
                            200: '#E4E4E7',  // 中灰
                            300: '#D4D4D8',  // 深灰
                            400: '#949499',  // 文本灰
                            500: '#6E6E73',  // 次要文本灰
                            600: '#3A3A3C',  // 主要文本灰
                        },
                        'base-bg': '#F5F5F7',  // 全局背景
                    },
                    fontFamily: {
                        sans: ['-apple-system', 'BlinkMacSystemFont', 'San Francisco', 'Helvetica Neue', 'Arial', 'sans-serif'],
                    },
                    boxShadow: {
                        'apple': '0 2px 10px rgba(0, 0, 0, 0.05)',  // 风格浅阴影
                        'apple-hover': '0 4px 15px rgba(0, 0, 0, 0.08)',  // hover阴影
                    },
                    borderRadius: {
                        'apple': '12px',  // 风格圆角
                    },
                    transitionTimingFunction: {
                        'apple': 'cubic-bezier(0.25, 0.1, 0.25, 1)',  // 过渡曲线
                    }
                }
            }
        }
    </script>
    
    <!-- 自定义工具类：风格动画与交互 -->
    <style type="text/tailwindcss">
        @layer utilities {
            .content-fit {
                content-visibility: auto;
            }
            .status-pulse {
                animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
            }
            .spin-slow {
                animation: spin 2s linear infinite;
            }
            .fade-in {
                animation: fadeIn 0.3s ease-in-out;
            }
            .slide-in-left {
                animation: slideInLeft 0.3s ease-in-out;
            }
            .btn-press {
                transition: transform 0.1s ease;
            }
            .btn-press:active {
                transform: scale(0.98);
            }
            .scrollbar-apple::-webkit-scrollbar {
                width: 6px;
                height: 6px;
            }
            .scrollbar-apple::-webkit-scrollbar-track {
                background: transparent;
            }
            .scrollbar-apple::-webkit-scrollbar-thumb {
                background: #D4D4D8;
                border-radius: 3px;
            }
            .scrollbar-apple::-webkit-scrollbar-thumb:hover {
                background: '#949499';
            }
            .blink-alert {
                animation: blink 1.5s infinite;
            }
            @keyframes pulse {
                0%, 100% { opacity: 1; }
                50% { opacity: 0.5; }
            }
            @keyframes spin {
                from { transform: rotate(0deg); }
                to { transform: rotate(360deg); }
            }
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(8px); }
                to { opacity: 1; transform: translateY(0); }
            }
            @keyframes slideInLeft {
                from { transform: translateX(-100%); }
                to { transform: translateX(0); }
            }
            @keyframes blink {
                0%, 100% { background-color: rgba(255, 59, 48, 0.1); border-left-color: #FF3B30; }
                50% { background-color: rgba(255, 59, 48, 0.3); border-left-color: #FF6B66; }
            }
        }
    </style>
    
    <!-- 固定导航栏样式保障 -->
    <style>
        #main-header {
            min-height: 48px; /* 固定导航栏高度 */
            transition: none !important; /* 禁用所有过渡动画 */
        }
        #main-header > .container {
            min-height: inherit;
        }
        
        /* 深色模式样式 */
        .dark {
            --tw-bg-opacity: 1;
            background-color: rgba(17, 24, 39, var(--tw-bg-opacity));
            color: rgba(229, 231, 235, var(--tw-text-opacity));
        }
        
        .dark .bg-white {
            background-color: rgba(31, 41, 55, var(--tw-bg-opacity));
        }
        
        .dark .text-neutral-600 {
            color: rgba(209, 213, 219, var(--tw-text-opacity));
        }
        
        .dark .text-neutral-400 {
            color: rgba(156, 163, 175, var(--tw-text-opacity));
        }
        
        .dark .border-neutral-100,
        .dark .border-neutral-200 {
            border-color: rgba(55, 65, 81, var(--tw-border-opacity));
        }
        
        .dark .bg-neutral-100 {
            background-color: rgba(55, 65, 81, var(--tw-bg-opacity));
        }
        
        .dark .bg-neutral-50 {
            background-color: rgba(31, 41, 55, var(--tw-bg-opacity));
        }
        
        .dark .shadow-apple {
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
        }
        
        .dark .divide-neutral-100 {
            border-color: rgba(55, 65, 81, var(--tw-border-opacity));
        }
        
        .realtime-badge {
            position: relative;
            top: -8px;
            right: -8px;
        }
    </style>
</head>
<body class="bg-base-bg font-sans text-neutral-600 min-h-screen overflow-x-hidden">
    <!-- 实时故障提醒条 -->
    <div id="real-time-alert" class="fixed top-0 left-0 right-0 bg-alert text-white py-2 px-4 z-50 flex items-center justify-between hidden" style="animation: blink 1s ease-in-out infinite;">
        <div class="flex items-center">
            <i class="fa fa-exclamation-circle mr-2 text-xl"></i>
            <div>
                <p class="font-medium">实时故障提醒</p>
                <p class="text-sm" id="alert-content">生产线M201发生填装装置填装故障4003，请处理</p>
            </div>
        </div>
        <button id="close-alert-btn" class="text-white hover:text-neutral-200 transition-colors">
            <i class="fa fa-times"></i>
        </button>
    </div>
    
    <!-- 头部导航（固定高度+禁用滚动动画） -->
    <header class="bg-white shadow-sm fixed top-0 left-0 right-0 z-50 min-h-[48px]" id="main-header">
        <div class="container mx-auto px-4 sm:px-6 lg:px-8 py-2 min-h-[48px] flex items-center justify-between gap-3">
            <!-- 左侧红圈区域：标题与侧边栏切换 -->
            <div class="flex items-center space-x-3 min-h-[40px]">
                <button id="sidebarToggle" class="btn-press p-2 rounded-full hover:bg-neutral-100 transition-colors" title="Toggle sidebar">
                    <i class="fa fa-bars text-neutral-500"></i>
                </button>
                <div class="flex items-center space-x-2">
                    <div class="w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center">
                        <i class="fa fa-cogs text-primary text-lg"></i>
                    </div>
                    <div>
                        <h1 class="text-lg font-semibold text-neutral-600">生产线智能检测系统</h1>
                    </div>
                </div>
            </div>
            
            <!-- 右侧红圈区域：管理员入口 + 实时监测状态提示 -->
            <div class="flex items-center space-x-3 min-h-[40px]">
                <!-- 实时监测状态提示（仅实时板块激活时显示） -->
                <div id="realtime-status-indicator" class="hidden items-center space-x-1 text-xs">
                    <span id="realtime-status-dot" class="inline-block w-2 h-2 rounded-full bg-neutral-300"></span>
                    <span id="realtime-status-text" class="text-neutral-500">实时监测未启动</span>
                </div>
                
                <button id="adminDropdownBtn" class="btn-press p-2 rounded-full hover:bg-neutral-100 transition-all" aria-expanded="false">
                    <i class="fa fa-user-circle-o text-neutral-500"></i>
                </button>
                <div id="adminDropdownMenu" class="absolute right-4 top-[48px] bg-white rounded-lg shadow-apple p-2 w-48 hidden fade-in" style="z-index: 60;">
                    <a href="#" class="btn-press block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors" data-target="profile-page">
                        <i class="fa fa-user-o mr-2 text-neutral-400"></i>个人信息
                    </a>
                    <a href="#" class="btn-press block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors" data-target="settings-page">
                        <i class="fa fa-cog mr-2 text-neutral-400"></i>系统设置
                    </a>
                </div>
            </div>
        </div>
    </header>
    
    <!-- 侧边栏（按需求调整导航排序） -->
    <aside id="globalSidebar" class="fixed top-[48px] left-0 w-44 h-[calc(100vh-48px)] bg-white shadow-apple z-50 transform -translate-x-full transition-transform duration-300 slide-in-left overflow-y-auto scrollbar-apple">
        <div class="p-3 border-b border-neutral-100">
            <h2 class="text-sm font-semibold text-neutral-500 uppercase tracking-wider">导航菜单</h2>
        </div>
        <nav class="p-2">
            <a href="#" class="sidebar-link block py-2 px-2 rounded-md text-sm text-primary bg-primary/5 font-medium transition-colors mb-1" data-target="overview-page">
                <i class="fa fa-dashboard mr-2 text-primary"></i>系统概览
            </a>
            <a href="#" class="sidebar-link block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors mb-1" data-target="fault-page">
                <i class="fa fa-exclamation-triangle mr-2 text-neutral-400"></i>
                故障实时检测
                <span id="realtime-alert-badge" class="inline-block w-4 h-4 rounded-full bg-alert text-white text-[10px] flex items-center justify-center realtime-badge hidden">0</span>
            </a>
            <a href="#" class="sidebar-link block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors mb-1" data-target="fault-date-query-page">
                <i class="fa fa-calendar-check-o mr-2 text-neutral-400"></i>故障日期查询
            </a>
            <a href="#" class="sidebar-link block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors mb-1" data-target="analysis-page">
                <i class="fa fa-bar-chart mr-2 text-neutral-400"></i>生产数据分析
            </a>
            <a href="#" class="sidebar-link block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors mb-1" data-target="schedule-page">
                <i class="fa fa-calendar mr-2 text-neutral-400"></i>排班优化
            </a>
            <a href="#" class="sidebar-link block py-2 px-3 rounded-md text-sm text-neutral-600 hover:bg-neutral-100 transition-colors mb-1" data-target="settings-page">
                <i class="fa fa-cog mr-2 text-neutral-400"></i>系统设置
            </a>
        </nav>
        <div class="absolute bottom-0 left-0 right-0 p-3 border-t border-neutral-100">
            <p class="text-xs text-neutral-400 text-center">版本：9.3 </p>
        </div>
    </aside>
    
    <!-- 主内容区（适配头部高度） -->
    <main class="container mx-auto px-4 sm:px-6 lg:px-8 pt-[64px] pb-12 transition-all duration-300" id="main-content">
        <!-- 系统概览页（仅保留4个2x2模块） -->
        <section id="overview-page" class="subpage block">
            <!-- 顶部统计卡片（2x2布局铺满页面） -->
            <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-6 mb-6">
                <!-- 故障识别准确率 -->
                <div class="bg-white rounded-lg shadow-apple p-6 hover:shadow-apple-hover transition-all duration-300 fade-in">
                    <div class="flex justify-between items-start mb-4">
                        <div>
                            <p class="text-base text-neutral-400">故障识别准确率</p>
                            <h3 id="accuracy-rate" class="text-3xl font-semibold text-primary mt-2">98.5%</h3>
                        </div>
                        <div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center">
                            <i class="fa fa-check-circle text-primary text-xl"></i>
                        </div>
                    </div>
                    <div class="flex items-center text-sm text-neutral-400">
                        <i class="fa fa-line-chart mr-1"></i>
                        <span id="accuracy-trend">较上月 +2.3%</span>
                    </div>
                </div>
                
                <!-- 生产线数量 -->
                <div class="bg-white rounded-lg shadow-apple p-6 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.1s">
                    <div class="flex justify-between items-start mb-4">
                        <div>
                            <p class="text-base text-neutral-400">生产线数量</p>
                            <h3 id="production-lines" class="text-3xl font-semibold text-info mt-2">8</h3>
                        </div>
                        <div class="w-12 h-12 rounded-full bg-info/10 flex items-center justify-center">
                            <i class="fa fa-cogs text-info text-xl"></i>
                        </div>
                    </div>
                    <div class="flex items-center text-sm text-neutral-400">
                        <i class="fa fa-industry mr-1"></i>
                        <span id="active-lines">正常运行: <span class="font-medium text-neutral-600">7</span>/8</span>
                    </div>
                </div>
                
                <!-- 操作人员 -->
                <div class="bg-white rounded-lg shadow-apple p-6 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.2s">
                    <div class="flex justify-between items-start mb-4">
                        <div>
                            <p class="text-base text-neutral-400">操作人员</p>
                            <h3 id="operators-count" class="text-3xl font-semibold text-secondary mt-2">42</h3>
                        </div>
                        <div class="w-12 h-12 rounded-full bg-secondary/10 flex items-center justify-center">
                            <i class="fa fa-users text-secondary text-xl"></i>
                        </div>
                    </div>
                    <div class="flex items-center text-sm text-neutral-400">
                        <i class="fa fa-clock-o mr-1"></i>
                        <span id="on-duty">在岗: <span class="font-medium text-neutral-600">36</span>/42</span>
                    </div>
                </div>
                
                <!-- 日净合格数 -->
                <div class="bg-white rounded-lg shadow-apple p-6 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.3s">
                    <div class="flex justify-between items-start mb-4">
                        <div>
                            <p class="text-base text-neutral-400">日净合格数</p>
                            <h3 id="daily-qualified" class="text-3xl font-semibold text-neutral-600 mt-2">12,583</h3>
                        </div>
                        <div class="w-12 h-12 rounded-full bg-neutral-100 flex items-center justify-center">
                            <i class="fa fa-bar-chart text-neutral-500 text-xl"></i>
                        </div>
                    </div>
                    <div class="flex items-center text-sm text-neutral-400">
                        <i class="fa fa-calendar mr-1"></i>
                        <span id="qualified-rate">合格率: <span class="font-medium text-neutral-600">98.2%</span></span>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- 故障实时检测子页面（整合index实时监测功能） -->
        <section id="fault-page" class="subpage hidden">
            <div class="bg-white rounded-lg shadow-apple p-4 mb-6 fade-in">
                <div class="flex flex-wrap items-center gap-3 w-full">
                    <!-- 生产线选择 -->
                    <div class="flex items-center space-x-2">
                        <label for="realtime-line-select" class="text-sm text-neutral-500">监测生产线:</label>
                        <select id="realtime-line-select" class="w-36 border border-neutral-200 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-white">
                            <option value="M201">M201生产线</option>
                            <option value="M202">M202生产线</option>
                        </select>
                    </div>
                    
                    <!-- 实时监测控制按钮 -->
                    <div class="flex items-center space-x-2">
                        <button id="start-monitor-btn" class="btn-press px-4 py-1.5 bg-secondary text-white rounded-lg text-sm hover:bg-secondary/90 transition-all flex items-center">
                            <i class="fa fa-play mr-1"></i>
                            <span>启动监测</span>
                        </button>
                        <button id="stop-monitor-btn" class="btn-press px-4 py-1.5 bg-alert text-white rounded-lg text-sm hover:bg-alert/90 transition-all flex items-center" disabled>
                            <i class="fa fa-stop mr-1"></i>
                            <span>停止监测</span>
                        </button>
                        <div id="realtime-loading-status" class="flex items-center space-x-1 text-sm text-neutral-500 hidden">
                            <i class="fa fa-circle-o-notch spin-slow text-primary"></i>
                            <span>操作中...</span>
                        </div>
                    </div>
                    
                    <!-- 实时监测信息 -->
                    <div class="flex items-center space-x-3 ml-auto text-sm">
                        <div class="flex items-center space-x-1">
                            <span class="text-neutral-500">监测频率:</span>
                            <span class="text-primary font-medium">3秒/次</span>
                        </div>
                        <div class="flex items-center space-x-1">
                            <span class="text-neutral-500">最后同步:</span>
                            <span id="realtime-last-sync" class="text-neutral-600">未同步</span>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 实时监测数据区 -->
            <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
                <!-- 1. 实时状态概览 -->
                <div class="lg:col-span-1 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                    <h2 class="text-lg font-semibold text-neutral-600 mb-4 flex items-center">
                        <i class="fa fa-tachometer mr-2 text-primary"></i>实时状态概览
                    </h2>
                    <div class="space-y-4">
                        <!-- 生产线状态 -->
                        <div class="flex justify-between items-center pb-2 border-b border-neutral-100">
                            <span class="text-sm text-neutral-500">生产线</span>
                            <span id="realtime-display-line" class="text-sm font-medium text-neutral-600">M201生产线</span>
                        </div>
                        <!-- 运行状态 -->
                        <div class="flex justify-between items-center pb-2 border-b border-neutral-100">
                            <span class="text-sm text-neutral-500">运行状态</span>
                            <span id="realtime-run-status" class="text-sm font-medium text-secondary">正常</span>
                        </div>
                        <!-- 活跃故障数 -->
                        <div class="flex justify-between items-center pb-2 border-b border-neutral-100">
                            <span class="text-sm text-neutral-500">活跃故障数</span>
                            <span id="realtime-active-count" class="text-sm font-medium text-neutral-600">0</span>
                        </div>
                        <!-- 今日故障总数 -->
                        <div class="flex justify-between items-center pb-2 border-b border-neutral-100">
                            <span class="text-sm text-neutral-500">今日故障总数</span>
                            <span id="realtime-total-count" class="text-sm font-medium text-neutral-600">0</span>
                        </div>
                        <!-- 最新故障 -->
                        <div>
                            <span class="text-sm text-neutral-500 block mb-1">最新故障</span>
                            <span id="realtime-latest-fault" class="text-sm text-neutral-400">无记录</span>
                        </div>
                    </div>
                </div>
                
                <!-- 2. 今日实时趋势 -->
                <div class="lg:col-span-2 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                    <div class="flex justify-between items-center mb-4">
                        <h2 class="text-lg font-semibold text-neutral-600 flex items-center">
                            <i class="fa fa-line-chart mr-2 text-primary"></i>今日故障实时趋势
                        </h2>
                        <div class="text-xs text-neutral-400">
                            数据更新: <span id="realtime-trend-update" class="text-neutral-600">未更新</span>
                        </div>
                    </div>
                    <div class="relative h-64">
                        <canvas id="realtime-trend-chart"></canvas>
                        <div id="realtime-trend-no-data" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 fade-in">
                            <i class="fa fa-area-chart text-neutral-200 text-2xl mb-2"></i>
                            <p class="text-neutral-400 text-sm">未启动实时监测或暂无数据</p>
                        </div>
                        <div id="realtime-trend-loading" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 hidden fade-in">
                            <i class="fa fa-circle-o-notch spin-slow text-primary text-xl mb-2"></i>
                            <p class="text-neutral-400 text-sm">加载实时趋势中...</p>
                        </div>
                    </div>
                </div>
                
                <!-- 3. 实时活跃故障列表 -->
                <div class="lg:col-span-1 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                    <h2 class="text-lg font-semibold text-neutral-600 mb-4 flex items-center">
                        <i class="fa fa-exclamation-circle mr-2 text-alert"></i>实时活跃故障
                        <span id="realtime-active-badge" class="ml-2 w-5 h-5 rounded-full bg-alert text-white text-[10px] flex items-center justify-center">0</span>
                    </h2>
                    <div id="realtime-active-container" class="max-h-80 overflow-y-auto pr-2 space-y-3 scrollbar-apple">
                        <div id="realtime-active-empty" class="py-8 text-center">
                            <i class="fa fa-check-circle text-secondary text-2xl mb-2"></i>
                            <p class="text-neutral-400 text-sm">当前无活跃故障</p>
                        </div>
                        <div id="realtime-active-loading" class="py-8 text-center hidden">
                            <i class="fa fa-circle-o-notch spin-slow text-primary text-xl mb-2"></i>
                            <p class="text-neutral-400 text-sm">加载活跃故障中...</p>
                        </div>
                    </div>
                </div>
                
                <!-- 4. 实时故障历史（最近10条） -->
                <div class="lg:col-span-2 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                    <div class="flex justify-between items-center mb-4">
                        <h2 class="text-lg font-semibold text-neutral-600 flex items-center">
                            <i class="fa fa-history mr-2 text-primary"></i>实时故障记录（最近10条）
                        </h2>
                        <button id="refresh-realtime-history" class="btn-press text-xs text-primary hover:text-primary/80 transition-colors flex items-center">
                            <i class="fa fa-refresh mr-1"></i>刷新
                        </button>
                    </div>
                    <div class="overflow-x-auto scrollbar-apple">
                        <table class="min-w-full divide-y divide-neutral-100">
                            <thead>
                                <tr class="bg-neutral-50">
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">ID</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">故障类型</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">开始时间</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">结束时间</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">持续时间</th>
                                    <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">状态</th>
                                </tr>
                            </thead>
                            <tbody id="realtime-history-body" class="bg-white divide-y divide-neutral-100">
                                <tr id="realtime-history-empty-row">
                                    <td colspan="6" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                        暂无实时故障记录
                                    </td>
                                </tr>
                                <tr id="realtime-history-loading-row" class="hidden">
                                    <td colspan="6" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                        <i class="fa fa-circle-o-notch spin-slow text-primary mr-2"></i>
                                        加载实时记录中...
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
            
            <!-- 实时数据详情面板 -->
            <div class="bg-white rounded-lg shadow-apple p-4 mb-8 fade-in">
                <div class="flex justify-between items-center mb-4">
                    <h2 class="text-lg font-semibold text-neutral-600 flex items-center">
                        <i class="fa fa-list-alt mr-2 text-primary"></i>实时数据详情
                    </h2>
                    <div class="text-xs text-neutral-400">
                        数据来源: <span id="realtime-data-source" class="text-neutral-600">M201生产线实时数据流</span>
                    </div>
                </div>
                <div class="overflow-x-auto scrollbar-apple">
                    <table class="min-w-full divide-y divide-neutral-100">
                        <thead>
                            <tr class="bg-neutral-50">
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">时间</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">故障类型</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">状态</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">物料推送数</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">物料待抓取数</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">放置容器数</th>
                                <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">容器上传检测数</th>
                            </tr>
                        </thead>
                        <tbody id="realtime-detail-body" class="bg-white divide-y divide-neutral-100">
                            <tr id="realtime-detail-empty-row">
                                <td colspan="7" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                    未启动实时监测或暂无数据
                                </td>
                            </tr>
                            <tr id="realtime-detail-loading-row" class="hidden">
                                <td colspan="7" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                    <i class="fa fa-circle-o-notch spin-slow text-primary mr-2"></i>
                                    加载实时详情中...
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <div class="mt-4 text-xs text-neutral-400 text-right">
                    注：实时数据最多保留最近20条，超出自动清理
                </div>
            </div>
        </section>
        
        <!-- 故障日期查询页面（整合index故障识别功能） -->
        <section id="fault-date-query-page" class="subpage hidden">
            <div class="bg-white rounded-lg shadow-apple p-4 mb-6 fade-in">
                <div class="flex flex-wrap items-center gap-2 sm:gap-3 w-full">
                    <!-- 生产线选择 -->
                    <div class="flex items-center space-x-2">
                        <label for="line-select" class="text-sm text-neutral-500">生产线:</label>
                        <select id="line-select" class="w-36 border border-neutral-200 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-white">
                            <option value="M201">M201生产线</option>
                            <option value="M202">M202生产线</option>
                        </select>
                    </div>
                    
                    <!-- 日期选择器 + 确认按钮 + 日期提示（水平对齐优化） -->
                    <div class="flex items-center gap-2">
                        <div class="flex items-center space-x-2 ml-2">
                            <label for="date-picker" class="text-sm text-neutral-500">日期:</label>
                            <input type="date" id="date-picker" class="w-36 border border-neutral-200 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-white"
                                   value="" min="2025-01-01" max="">
                            <button id="date-confirm-btn" class="btn-press px-4 py-1.5 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all" aria-label="确认日期并加载数据">
                                <i class="fa fa-check mr-1"></i>确认
                            </button>
                        </div>
                        <div id="date-tip" class="text-xs text-neutral-400 mt-0.5 inline-block">
                        </div>
                    </div>
                    
                    <!-- 操作按钮组 -->
                    <div class="flex items-center space-x-2">
                        <button id="refresh-btn" class="btn-press flex items-center space-x-1 px-3 py-1.5 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all" aria-label="刷新当前日期数据" disabled>
                            <i class="fa fa-refresh" id="refresh-icon"></i>
                            <span>刷新</span>
                        </button>
                        <button id="clear-cache-btn" class="btn-press flex items-center space-x-1 px-3 py-1.5 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all" aria-label="清空缓存" disabled>
                            <i class="fa fa-trash-o"></i>
                            <span>清空缓存</span>
                        </button>
                        <div id="loading-status" class="flex items-center space-x-1 text-sm text-neutral-500 hidden">
                            <i class="fa fa-circle-o-notch spin-slow text-primary"></i>
                            <span>处理中...</span>
                        </div>
                    </div>
                    
                    <!-- 最后更新时间 -->
                    <div id="last-update-container" class="text-xs text-neutral-400 ml-auto hidden">
                        最后更新: <span id="last-update-time">未更新</span>
                    </div>
                </div>
            </div>
            
            <!-- 初始空状态 -->
            <div id="initial-empty-state" class="flex flex-col items-center justify-center h-[50vh] text-center fade-in">
                <div class="w-16 h-16 rounded-full bg-neutral-100 flex items-center justify-center mb-4">
                    <i class="fa fa-calendar-check-o text-neutral-300 text-2xl"></i>
                </div>
                <h3 class="text-lg font-semibold text-neutral-600 mb-2">未选择查询日期</h3>
                <p class="text-neutral-400 max-w-md">请在上方选择生产线和目标日期，点击"确认"按钮后加载对应日期的故障监测数据</p>
            </div>
            
            <!-- 数据内容区 -->
            <div id="data-content" class="hidden">
                <!-- 1. 状态概览卡片区 -->
                <section class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
                    <div class="bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                        <div class="flex justify-between items-start mb-3">
                            <div>
                                <p class="text-sm text-neutral-400">整体运行状态</p>
                                <h3 id="overall-status" class="text-2xl font-semibold text-secondary mt-1">正常</h3>
                            </div>
                            <div id="status-indicator" class="w-10 h-10 rounded-full bg-secondary/10 flex items-center justify-center">
                                <i class="fa fa-check text-secondary"></i>
                            </div>
                        </div>
                        <div class="flex items-center text-xs text-neutral-400">
                            <i class="fa fa-calendar-o mr-1"></i>
                            <span>当前查询日期: </span>
                            <span id="display-date" class="font-medium text-neutral-600 ml-1">--</span>
                        </div>
                    </div>
                    <div class="bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.1s">
                        <div class="flex justify-between items-start mb-3">
                            <div>
                                <p class="text-sm text-neutral-400">活跃故障数</p>
                                <h3 id="active-fault-count" class="text-2xl font-semibold text-neutral-600 mt-1">0</h3>
                            </div>
                            <div class="w-10 h-10 rounded-full bg-alert/10 flex items-center justify-center">
                                <i class="fa fa-exclamation-triangle text-alert"></i>
                            </div>
                        </div>
                        <div class="flex items-center text-xs text-neutral-400">
                            <i class="fa fa-clock-o mr-1"></i>
                            <span>最近故障: </span>
                            <span id="latest-fault-info" class="ml-1">无记录</span>
                        </div>
                    </div>
                    <div class="bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.2s">
                        <div class="flex justify-between items-start mb-3">
                            <div>
                                <p class="text-sm text-neutral-400">当日故障总数</p>
                                <h3 id="total-fault-count" class="text-2xl font-semibold text-neutral-600 mt-1">0</h3>
                            </div>
                            <div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center">
                                <i class="fa fa-bar-chart text-primary"></i>
                            </div>
                        </div>
                        <div class="flex items-center text-xs text-neutral-400">
                            <i class="fa fa-database mr-1"></i>
                            <span>处理数据行数: </span>
                            <span id="processed-rows" class="font-medium text-neutral-600 ml-1">0</span>
                        </div>
                    </div>
                    <div class="bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in" style="animation-delay: 0.3s">
                        <div class="flex justify-between items-start mb-3">
                            <div>
                                <p class="text-sm text-neutral-400">故障高峰时段</p>
                                <h3 id="peak-time" class="text-2xl font-semibold text-neutral-600 mt-1">--:--</h3>
                            </div>
                            <div class="w-10 h-10 rounded-full bg-neutral-100 flex items-center justify-center">
                                <i class="fa fa-line-chart text-neutral-500"></i>
                            </div>
                        </div>
                        <div class="flex items-center text-xs text-neutral-400">
                            <i class="fa fa-signal mr-1"></i>
                            <span>高峰故障数: </span>
                            <span id="peak-fault-count" class="font-medium text-neutral-600 ml-1">0</span>
                        </div>
                    </div>
                </section>
                
                <!-- 2. 图表与数据列表区 -->
                <section class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
                    <div class="lg:col-span-1 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-lg font-semibold text-neutral-600">故障类型分布</h2>
                            <button id="refresh-type-chart" class="btn-press text-xs text-primary hover:text-primary/80 transition-colors flex items-center" onclick="refreshFaultTypeChart()">
                                <i class="fa fa-refresh mr-1"></i>刷新
                            </button>
                        </div>
                        <div class="relative h-64">
                            <canvas id="fault-type-chart"></canvas>
                            <div id="type-chart-no-data" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 hidden fade-in">
                                <i class="fa fa-pie-chart text-neutral-200 text-2xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">暂无故障类型数据</p>
                            </div>
                            <div id="type-chart-loading" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 hidden fade-in">
                                <i class="fa fa-circle-o-notch spin-slow text-primary text-xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">加载图表中...</p>
                            </div>
                        </div>
                    </div>
                    <div class="lg:col-span-2 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-lg font-semibold text-neutral-600">当日故障时间趋势</h2>
                            <div class="text-xs text-neutral-400">
                                时间粒度: <span class="text-primary font-medium">1小时/段</span>
                            </div>
                        </div>
                        <div class="relative h-64">
                            <canvas id="fault-trend-chart"></canvas>
                            <div id="trend-chart-no-data" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 hidden fade-in">
                                <i class="fa fa-area-chart text-neutral-200 text-2xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">暂无故障趋势数据</p>
                            </div>
                            <div id="trend-chart-loading" class="absolute inset-0 flex flex-col items-center justify-center bg-white/90 z-10 hidden fade-in">
                                <i class="fa fa-circle-o-notch spin-slow text-primary text-xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">加载图表中...</p>
                            </div>
                        </div>
                    </div>
                    <div class="lg:col-span-1 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                        <h2 class="text-lg font-semibold text-neutral-600 mb-4">当前活跃故障</h2>
                        <div id="active-faults-container" class="max-h-80 overflow-y-auto pr-2 space-y-3 scrollbar-apple">
                            <div id="active-faults-empty" class="py-8 text-center">
                                <i class="fa fa-check-circle text-secondary text-2xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">当前无活跃故障</p>
                            </div>
                            <div id="active-faults-loading" class="py-8 text-center hidden">
                                <i class="fa fa-circle-o-notch spin-slow text-primary text-xl mb-2"></i>
                                <p class="text-neutral-400 text-sm">加载活跃故障中...</p>
                            </div>
                        </div>
                    </div>
                    <div class="lg:col-span-2 bg-white rounded-lg shadow-apple p-4 hover:shadow-apple-hover transition-all duration-300 fade-in">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-lg font-semibold text-neutral-600">故障历史记录</h2>
                            <div class="flex items-center space-x-2 text-sm">
                                <button id="prev-page-btn" class="btn-press px-2 py-1 border border-neutral-200 rounded-lg hover:bg-neutral-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors" onclick="changePage(-1)" disabled>
                                    <i class="fa fa-chevron-left"></i>
                                </button>
                                <span id="page-display">
                                    第 <span id="current-page">1</span> 页 / 共 <span id="total-pages">1</span> 页
                                </span>
                                <button id="next-page-btn" class="btn-press px-2 py-1 border border-neutral-200 rounded-lg hover:bg-neutral-100 disabled:opacity-50 disabled:cursor-not-allowed transition-colors" onclick="changePage(1)" disabled>
                                    <i class="fa fa-chevron-right"></i>
                                </button>
                            </div>
                        </div>
                        <div class="overflow-x-auto scrollbar-apple">
                            <table class="min-w-full divide-y divide-neutral-100">
                                <thead>
                                    <tr class="bg-neutral-50">
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">ID</th>
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">故障类型</th>
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">开始时间</th>
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">结束时间</th>
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">持续时间</th>
                                        <th class="px-4 py-3 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider">操作</th>
                                    </tr>
                                </thead>
                                <tbody id="history-table-body" class="bg-white divide-y divide-neutral-100">
                                    <tr id="history-empty-row">
                                        <td colspan="6" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                            暂无故障历史记录
                                        </td>
                                    </tr>
                                    <tr id="history-loading-row" class="hidden">
                                        <td colspan="6" class="px-4 py-8 text-center text-neutral-400 text-sm">
                                            <i class="fa fa-circle-o-notch spin-slow text-primary mr-2"></i>
                                            加载历史记录中...
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </section>
            </div>
        </section>
        
        <!-- 生产数据分析页 -->
        <section id="analysis-page" class="subpage hidden">
            <div class="bg-white rounded-lg shadow-apple p-6 mb-6 fade-in">
                <h2 class="text-xl font-semibold text-neutral-600 mb-4 flex items-center">
                    <i class="fa fa-bar-chart mr-2 text-primary"></i>生产数据分析
                </h2>
                
                <div class="controls flex flex-wrap items-center gap-4 mb-6">
                    <div class="flex items-center space-x-2">
                        <label for="lineSelect" class="text-sm text-neutral-500">选择生产线:</label>
                        <select id="lineSelect" class="w-48 border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-white">
                            <option value="">请选择生产线</option>
                        </select>
                    </div>
                    
                    <div class="flex items-center space-x-2">
                        <button id="viewLineBtn" class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all">
                            查看生产线图表
                        </button>
                        <button id="viewSummaryBtn" class="btn-press px-4 py-2 bg-secondary text-white rounded-lg text-sm hover:bg-secondary/90 transition-all">
                            查看汇总图表
                        </button>
                    </div>
                </div>
                
                <div id="chartContainer" class="chart-container grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    <div class="empty-tip text-center py-12 text-neutral-400 col-span-full">
                        请选择生产线或点击"查看汇总图表"按钮加载图表
                    </div>
                </div>
            </div>

            <script>
                const chartContainer = document.getElementById("chartContainer");
                const lineSelect = document.getElementById("lineSelect");
                const viewLineBtn = document.getElementById("viewLineBtn");
                const viewSummaryBtn = document.getElementById("viewSummaryBtn");

                // 后端接口基础路径（当前页面与后端同域，用相对路径）
                const baseUrl = "";

                // 页面加载时，获取所有生产线编号并填充下拉框
                fetch(`${baseUrl}/api/production-lines`)
                    .then(response => response.json())
                    .then(data => {
                        data.productionLines.forEach(line => {
                            const option = document.createElement("option");
                            option.value = line;
                            option.textContent = line;
                            lineSelect.appendChild(option);
                        });
                    })
                    .catch(error => {
                        console.error("获取生产线列表失败：", error);
                        chartContainer.innerHTML = '<div class="empty-tip">获取生产线列表失败，请检查后端服务</div>';
                    });

                // 查看生产线图表按钮点击事件
                viewLineBtn.addEventListener("click", () => {
                    const line = lineSelect.value;
                    if (!line) {
                        alert("请选择生产线");
                        return;
                    }
                    chartContainer.innerHTML = '<div class="empty-tip">图表加载中...</div>';
                    fetch(`${baseUrl}/api/line-charts?line=${line}`)
                        .then(response => response.json())
                        .then(data => {
                            renderCharts(data.charts);
                        })
                        .catch(error => {
                            console.error("获取生产线图表失败：", error);
                            chartContainer.innerHTML = '<div class="empty-tip">获取生产线图表失败</div>';
                        });
                });

                // 查看汇总图表按钮点击事件
                viewSummaryBtn.addEventListener("click", () => {
                    chartContainer.innerHTML = '<div class="empty-tip">汇总图表加载中...</div>';
                    fetch(`${baseUrl}/api/summary-charts`)
                        .then(response => response.json())
                        .then(data => {
                            renderCharts(data.charts);
                        })
                        .catch(error => {
                            console.error("获取汇总图表失败：", error);
                            chartContainer.innerHTML = '<div class="empty-tip">获取汇总图表失败</div>';
                        });
                });

                // 渲染图表到页面的函数
                function renderCharts(chartNames) {
                    chartContainer.innerHTML = "";
                    if (chartNames.length === 0) {
                        chartContainer.innerHTML = '<div class="empty-tip">未找到对应图表，请检查生产线选择或图表文件</div>';
                        return;
                    }
                    chartNames.forEach(name => {
                        const chartItem = document.createElement("div");
                        chartItem.className = "chart-item";
                        
                        const title = document.createElement("div");
                        title.className = "chart-title";
                        title.textContent = name.replace(".png", "");
                        
                        const img = document.createElement("img");
                        img.src = `${baseUrl}/charts/${name}`;
                        img.alt = name;
                        // 图片加载失败时的处理
                        img.onerror = function() {
                            this.src = "data:image/svg+xml;charset=UTF-8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='200' viewBox='0 0 300 200'><rect width='300' height='200' fill='%23f5f5f5'/><text x='150' y='100' text-anchor='middle' fill='%23999' font-size='14'>图表加载失败</text></svg>";
                            this.alt = "图表加载失败";
                        };
                        
                        chartItem.appendChild(title);
                        chartItem.appendChild(img);
                        chartContainer.appendChild(chartItem);
                    });
                }
            </script>
        </section>
                
        <!-- 排班优化页 -->
        <section id="schedule-page" class="subpage hidden">
            <!-- 工龄配置面板 -->
            <div class="bg-white rounded-lg shadow-apple p-6 mb-6 fade-in">
                <h2 class="text-xl font-semibold text-neutral-600 mb-4">工龄人数配置</h2>
                <form id="age-config-form" class="mb-6">
                    <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
                        <div>
                            <label for="age1" class="block text-sm font-medium text-neutral-500 mb-1">工龄1年</label>
                            <input type="number" id="age1" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1" max="37" value="8" onchange="calculateTotal()">
                        </div>
                        <div>
                            <label for="age2" class="block text-sm font-medium text-neutral-500 mb-1">工龄2年</label>
                            <input type="number" id="age2" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1" max="30" value="8" onchange="calculateTotal()">
                        </div>
                        <div>
                            <label for="age3" class="block text-sm font-medium text-neutral-500 mb-1">工龄3年</label>
                            <input type="number" id="age3" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1" max="23" value="4" onchange="calculateTotal()">
                        </div>
                        <div>
                            <label for="age4" class="block text-sm font-medium text-neutral-500 mb-1">工龄4年</label>
                            <input type="number" id="age4" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1, 20" value="8" onchange="calculateTotal()">
                        </div>
                        <div>
                            <label for="age5" class="block text-sm font-medium text-neutral-500 mb-1">工龄5年</label>
                            <input type="number" id="age5" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1" max="13" value="9" onchange="calculateTotal()">
                        </div>
                        <div>
                            <label for="age6" class="block text-sm font-medium text-neutral-500 mb-1">工龄6年</label>
                            <input type="number" id="age6" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all" min="1" max="5" value="5" onchange="calculateTotal()">
                        </div>
                    </div>
                </form>
                
                <div class="flex items-center justify-between">
                    <div class="flex items-center">
                        <span class="text-sm text-neutral-500 mr-2">总人数:</span>
                        <span id="total-workers" class="text-lg font-semibold text-primary">42</span>
                        <span class="text-sm text-neutral-400 ml-1">/ 42 (需求人数)</span>
                    </div>
                    <button id="btn-update" class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all" onclick="updateSchedule()">
                        更新排班
                    </button>
                </div>
                
                <div id="config-message" class="mt-4 p-3 rounded-lg hidden">
                    <!-- 消息提示区域 -->
                </div>
            </div>
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
                <!-- 个人排班表 -->
                <div class="bg-white rounded-lg shadow-apple p-6 fade-in">
                    <div class="flex justify-between items-center mb-4">
                        <h3 class="text-lg font-semibold text-neutral-600">个人排班表</h3>
                        <div class="flex space-x-2">
                            <button class="btn-press p-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all" onclick="loadScheduleData()">
                                <i class="fa fa-refresh"></i>
                            </button>
                            <button class="btn-press px-3 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all" onclick="downloadScheduleFile('result1')">
                                下载Excel
                            </button>
                        </div>
                    </div>
                    <div class="overflow-x-auto scrollbar-apple max-h-96">
                        <table class="min-w-full divide-y divide-neutral-100">
                            <thead class="bg-neutral-50">
                                <tr id="table1-header"></tr>
                            </thead>
                            <tbody id="table1-body" class="divide-y divide-neutral-100"></tbody>
                        </table>
                    </div>
                </div>
                
                <!-- 班组排班表 -->
                <div class="bg-white rounded-lg shadow-apple p-6 fade-in">
                    <div class="flex justify-between items-center mb-4">
                        <h3 class="text-lg font-semibold text-neutral-600">班组排班表</h3>
                        <div class="flex space-x-2">
                            <button class="btn-press p-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all" onclick="loadScheduleData()">
                                <i class="fa fa-refresh"></i>
                            </button>
                            <button class="btn-press px-3 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all" onclick="downloadScheduleFile('result2')">
                                下载Excel
                            </button>
                        </div>
                    </div>
                    <div class="overflow-x-auto scrollbar-apple max-h-96">
                        <table class="min-w-full divide-y divide-neutral-100">
                            <thead class="bg-neutral-50">
                                <tr id="table2-header"></tr>
                            </thead>
                            <tbody id="table2-body" class="divide-y divide-neutral-100"></tbody>
                        </table>
                    </div>
                </div>
            </div>
            <div class="mt-6 text-center">
                <p class="text-sm text-neutral-400" id="last-updated">
                    最后更新时间: <span id="update-time">加载中...</span>
                </p>
            </div>
        </section>
        
        <!-- 系统设置页 -->
        <section id="settings-page" class="subpage hidden">
            <div class="p-6 bg-white rounded-lg shadow-apple mb-6 fade-in">
                <h2 class="text-xl font-semibold text-neutral-600 mb-4">系统设置</h2>
                
                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                    <!-- 主题设置 -->
                    <div class="bg-neutral-50 rounded-xl p-5">
                        <h3 class="text-lg font-medium text-neutral-600 mb-4 flex items-center">
                            <i class="fa fa-paint-brush mr-2 text-primary"></i>主题设置
                        </h3>
                        <div class="space-y-4">
                            <div class="flex items-center justify-between">
    <span class="text-neutral-500">界面主题</span>
    <select id="theme-select" class="border border-neutral-200 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-white w-32">
        <option value="light">浅色模式</option>
        <option value="dark">深色模式</option>
        <option value="auto">自动</option>
    </select>
</div>
                        </div>
                    </div>
                    
                                       <!-- 通知设置 -->
                    <div class="bg-neutral-50 rounded-xl p-5">
                        <h3 class="text-lg font-medium text-neutral-600 mb-4 flex items-center">
                            <i class="fa fa-bell mr-2 text-primary"></i>通知设置
                        </h3>
                        <div class="space-y-4">
                            <div class="flex items-center justify-between">
                                <span class="text-neutral-500">故障通知</span>
                                <label class="relative inline-flex items-center cursor-pointer">
                                    <input type="checkbox" class="sr-only peer" checked>
                                    <div class="w-11 h-6 bg-neutral-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                                </label>
                            </div>
                            <div class="flex items-center justify-between">
                                <span class="text-neutral-500">邮件提醒</span>
                                <label class="relative inline-flex items center cursor-pointer">
                                    <input type="checkbox" class="sr-only peer">
                                    <div class="w-11 h-6 bg-neutral-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                                </label>
                            </div>
                            <div class="flex items-center justify-between">
                                <span class="text-neutral-500">声音提醒</span>
                                <label class="relative inline-flex items-center cursor-pointer">
                                    <input type="checkbox" class="sr-only peer" checked>
                                    <div class="w-11 h-6 bg-neutral-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary"></div>
                                </label>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 数据管理 -->
                    <div class="bg-neutral-50 rounded-xl p-5">
                        <h3 class="text-lg font-medium text-neutral-600 mb-4 flex items-center">
                            <i class="fa fa-database mr-2 text-primary"></i>数据管理
                        </h3>
                        <div class="space-y-4">
                            <div>
                                <p class="text-sm text-neutral-500 mb-2">缓存数据</p>
                                <button class="btn-press w-full px-4 py-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all flex items-center justify-center">
                                    <i class="fa fa-trash-o mr-2"></i>清空缓存数据
                                </button>
                            </div>
                            <div>
                                <p class="text-sm text-neutral-500 mb-2">数据导出</p>
                                <button class="btn-press w-full px-4 py-2 bg-primary/10 text-primary rounded-lg text-sm hover:bg-primary/20 transition-all flex items-center justify-center">
                                    <i class="fa fa-download mr-2"></i>导出历史数据
                                </button>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 系统信息 -->
                    <div class="bg-neutral-50 rounded-xl p-5">
                        <h3 class="text-lg font-medium text-neutral-600 mb-4 flex items-center">
                            <i class="fa fa-info-circle mr-2 text-primary"></i>系统信息
                        </h3>
                        <div class="space-y-3">
                            <div class="flex justify-between">
                                <span class="text-neutral-500">系统版本</span>
                                <span class="text-neutral-600 font-medium">v1.0.0</span>
                            </div>
                            <div class="flex justify-between">
                                <span class="text-neutral-500">最后更新</span>
                                <span class="text-neutral-600 font-medium">2025-09-25</span>
                            </div>
                            <div class="flex justify-between">
                                <span class="text-neutral-500">数据最后同步</span>
                                <span class="text-neutral-600 font-medium">2023-09-25 18:30</span>
                            </div>
                            <div class="pt-3 border-t border-neutral-200">
                                <button class="btn-press w-full px-4 py-2 bg-white border border-neutral-200 text-neutral-600 rounded-lg text-sm hover:bg-neutral-50 transition-all flex items-center justify-center">
                                    <i class="fa fa-refresh mr-2"></i>检查更新
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="mt-6 flex justify-end">
                    <button class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all mr-2">
                        保存设置
                    </button>
                    <button class="btn-press px-4 py-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all">
                        恢复默认
                    </button>
                </div>
            </div>
        </section>
        
        <!-- 个人信息页 -->
        <section id="profile-page" class="subpage hidden">
            <div class="p-6 bg-white rounded-lg shadow-apple mb-6 fade-in">
                <h2 class="text-xl font-semibold text-neutral-600 mb-6 flex items-center">
                    <i class="fa fa-user-circle-o mr-2 text-primary"></i>个人信息
                </h2>
                
                <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
                    <!-- 用户信息卡片 -->
                    <div class="md:col-span-1">
                        <div class="bg-neutral-50 rounded-xl p-5 text-center">
                            <div class="w-24 h-24 rounded-full bg-primary/10 flex items-center justify-center mx-auto mb-4">
                                <i class="fa fa-user-o text-primary text-3xl"></i>
                            </div>
                            <h3 class="text-lg font-semibold text-neutral-600" id="profile-display-name">张经理</h3>
                            <p class="text-sm text-neutral-400 mb-2" id="profile-display-position">系统管理员</p>
                            <p class="text-xs text-neutral-400" id="profile-display-department">生产管理部</p>
                        </div>
                    </div>
                    
                    <!-- 详细信息 -->
                    <div class="md:col-span-2">
                        <div class="bg-neutral-50 rounded-xl p-5">
                            <h3 class="text-lg font-medium text-neutral-600 mb-4">基本信息</h3>
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">姓名</label>
                                    <input type="text" id="profile-name" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                                </div>
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">工号</label>
                                    <input type="text" id="profile-employee-id" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all bg-neutral-100" disabled>
                                </div>
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">部门</label>
                                    <input type="text" id="profile-department" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                                </div>
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">职位</label>
                                    <input type="text" id="profile-position" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                                </div>
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">邮箱</label>
                                    <input type="email" id="profile-email" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                                </div>
                                <div>
                                    <label class="block text-sm text-neutral-500 mb-1">手机号</label>
                                    <input type="tel" id="profile-phone" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
            <!-- 修改密码 -->
            <div class="bg-neutral-50 rounded-xl p-5 mb-6">
                <h3 class="text-lg font-medium text-neutral-600 mb-4 flex items-center">
                    <i class="fa fa-lock mr-2 text-primary"></i>修改密码
                </h3>
                <!-- 修改密码部分，确保input有正确的ID -->
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                        <label class="block text-sm text-neutral-500 mb-1">当前密码</label>
                        <input type="password" id="current-password" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                    </div>
                    <div>
                        <label class="block text-sm text-neutral-500 mb-1">新密码</label>
                        <input type="password" id="new-password" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                    </div>
                    <div>
                        <label class="block text-sm text-neutral-500 mb-1">确认新密码</label>
                        <input type="password" id="confirm-password" class="w-full border border-neutral-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary transition-all">
                    </div>
                    <div class="flex items-end">
                        <button type="button" class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all" onclick="changePassword()">
                            更新密码
                        </button>
                    </div>
                </div>
            </div>
                
                <div class="flex justify-end">
                    <button class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all mr-2" onclick="saveProfile()">
                        保存更改
                    </button>
                    <button class="btn-press px-4 py-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all" onclick="resetProfile()">
                        取消
                    </button>
                </div>
            </div>
        </section>
</main>

<!-- 故障详情弹窗 -->
<div id="fault-detail-modal" class="fixed inset-0 bg-black/30 z-50 flex items-center justify-center hidden fade-in" role="dialog" aria-modal="true">
    <div class="bg-white rounded-lg shadow-lg w-full max-w-lg max-h-[85vh] overflow-y-auto m-4 scrollbar-apple transform transition-all scale-95 opacity-0" id="modal-content-wrapper">
        <div class="p-5 border-b border-neutral-100 flex justify-between items-center">
            <h3 class="text-lg font-semibold text-neutral-600" id="modal-title">故障详情</h3>
            <button id="close-modal-btn" class="btn-press p-2 rounded-full hover:bg-neutral-100 transition-colors" aria-label="关闭弹窗">
                <i class="fa fa-times text-neutral-400"></i>
            </button>
        </div>
        <div class="p-5 space-y-4" id="modal-body">
            <!-- 动态内容 -->
        </div>
        <div class="p-4 border-t border-neutral-100 flex justify-end">
            <button id="confirm-modal-btn" class="btn-press px-4 py-2 bg-neutral-100 text-neutral-600 rounded-lg text-sm hover:bg-neutral-200 transition-all">
                关闭
            </button>
        </div>
    </div>
</div>

<!-- 提示弹窗 -->
<div id="alert-modal" class="fixed inset-0 bg-black/30 z-50 flex items-center justify-center hidden fade-in" role="dialog" aria-modal="true">
    <div class="bg-white rounded-lg shadow-lg w-full max-w-md m-4">
        <div class="p-5 flex items-start space-x-3">
            <div id="alert-icon-container" class="w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0">
                <i class="fa fa-info-circle text-primary" id="alert-icon"></i>
            </div>
            <div>
                <h4 class="text-lg font-semibold text-neutral-600" id="alert-title">提示信息</h4>
                <p class="text-neutral-400 mt-1 text-sm" id="alert-message">操作已完成</p>
            </div>
        </div>
        <div class="p-4 border-t border-neutral-100 flex justify-end">
            <button id="confirm-alert-btn" class="btn-press px-4 py-2 bg-primary text-white rounded-lg text-sm hover:bg-primary/90 transition-all">
                确认
            </button>
        </div>
    </div>
</div>

<!-- 核心JS逻辑（整合鲲鹏9.4原有逻辑 + index实时/日期查询功能） -->
<script>
    // ---------------------- 全局变量定义（按功能模块隔离） ----------------------
    // 鲲鹏9.4原有全局变量
    let socket;                   // WebSocket实例
    let realTimeRunning = false;   // 原实时监测状态（兼容用，实际使用realtimeModule.isRunning）
    
    // 历史故障日期查询模块变量（来自index）
    let faultTypeChart, faultTrendChart;
    let fullFaultHistory = [];
    let dataCache = new Map();
    let currentPage = 1;
    const PAGE_SIZE = 10;
    const CACHE_TTL = 5 * 60 * 1000;
    let hasInitiatedDataLoad = false;
    
    // 实时监测模块变量（来自index，独立命名空间）
    const realtimeModule = {
        monitorInterval: null,    // 实时监测定时器
        isRunning: false,         // 实时监测状态
        activeFaults: [],         // 实时活跃故障列表
        detailData: [],           // 实时数据详情列表
        MAX_DETAIL_RECORDS: 20    // 实时详情最大记录数
    };

    // 在现有JavaScript代码之前添加
    // 登录状态验证
    function checkLoginStatus() {
        const token = localStorage.getItem('authToken');
        
        // 验证token有效性
        fetch('/api/login', {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        })
        .then(response => response.json())
        .then(data => {
            if (!data.success) {
                localStorage.removeItem('authToken');
                localStorage.removeItem('userInfo');
                
            } else {
                // 更新用户信息显示
                const userInfo = data.user;
                // 可以在这里更新页面上的用户信息
                console.log('当前用户:', userInfo);
            }
        })
        .catch(error => {
            console.error('验证登录状态失败:', error);
            localStorage.removeItem('authToken');
            localStorage.removeItem('userInfo');
            
        });
    }

    // 登出功能
    function logout() {
        const token = localStorage.getItem('authToken');
        
        fetch('/api/logout', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
            }
        })
        .then(() => {
            localStorage.removeItem('authToken');
            localStorage.removeItem('userInfo');
            localStorage.removeItem('rememberedUsername');
            window.location.href = '/login';
        })
        .catch(error => {
            console.error('登出失败:', error);
            // 即使请求失败也清除本地数据
            localStorage.removeItem('authToken');
            localStorage.removeItem('userInfo');
            localStorage.removeItem('rememberedUsername');
            window.location.href = '/login';
        });
    }

    // 在页面加载时检查登录状态
    document.addEventListener('DOMContentLoaded', function() {
        checkLoginStatus();
        
        // 为管理员菜单添加登出功能
        const logoutLink = document.createElement('a');
        logoutLink.href = '#';
        logoutLink.className = 'btn-press block py-2 px-3 rounded-md text-sm text-alert hover:bg-alert/10 transition-colors';
        logoutLink.innerHTML = '<i class="fa fa-sign-out mr-2 text-alert/70"></i>退出登录';
        logoutLink.onclick = function(e) {
            e.preventDefault();
            logout();
        };
        
        // 添加到管理员下拉菜单
        const adminMenu = document.getElementById('adminDropdownMenu');
        if (adminMenu) {
            adminMenu.appendChild(logoutLink);
        }
    });
    
    // 个人信息管理功能
    function initProfilePage() {
        // 从localStorage获取用户信息
        const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
        const token = localStorage.getItem('authToken');
        
        if (userInfo && userInfo.name) {
            // 填充基本信息
            $('#profile-display-name').textContent = userInfo.name || '未设置';
            $('#profile-display-position').textContent = userInfo.position || '未设置';
            $('#profile-display-department').textContent = userInfo.department || '未设置';
            
            // 填充表单字段
            $('#profile-name').value = userInfo.name || '';
            $('#profile-employee-id').value = userInfo.employee_id || '';
            $('#profile-department').value = userInfo.department || '';
            $('#profile-position').value = userInfo.position || '';
            $('#profile-email').value = userInfo.email || '';
            $('#profile-phone').value = userInfo.phone || '';
        } else if (token) {
            // 如果有token但没用户信息，尝试从API获取
            fetchUserProfile();
        }
    }

    // 从API获取用户详细信息
    async function fetchUserProfile() {
        try {
            const token = localStorage.getItem('authToken');
            const response = await fetch('/api/user/profile', {
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json'
                }
            });
            
            if (response.ok) {
                const data = await response.json();
                if (data.success && data.user_info) {
                    // 保存到localStorage
                    localStorage.setItem('userInfo', JSON.stringify(data.user_info));
                    // 更新页面显示
                    initProfilePage();
                }
            }
        } catch (error) {
            console.error('获取用户信息失败:', error);
        }
    }

    // 保存个人信息
    async function saveProfile() {
        try {
            const profileData = {
                name: $('#profile-name').value,
                department: $('#profile-department').value,
                position: $('#profile-position').value,
                email: $('#profile-email').value,
                phone: $('#profile-phone').value
            };

            const token = localStorage.getItem('authToken');
            const response = await fetch('/api/user/update-profile', {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(profileData)
            });

            const result = await response.json();
            
            if (result.success) {
                showAlertModal('成功', '个人信息更新成功', 'success');
                // 更新本地存储
                const currentUserInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
                const updatedUserInfo = { ...currentUserInfo, ...profileData };
                localStorage.setItem('userInfo', JSON.stringify(updatedUserInfo));
            } else {
                showAlertModal('错误', result.message || '更新失败', 'error');
            }
        } catch (error) {
            console.error('保存个人信息失败:', error);
            showAlertModal('错误', '网络错误，请重试', 'error');
        }
    }

    // 重置个人信息表单
    function resetProfile() {
        initProfilePage(); // 重新从localStorage加载原始数据
    }

    // 修改密码功能
    async function changePassword() {
        const currentPassword = $('#current-password').value;
        const newPassword = $('#new-password').value;
        const confirmPassword = $('#confirm-password').value;

        if (!currentPassword || !newPassword || !confirmPassword) {
            showAlertModal('错误', '请填写所有密码字段', 'error');
            return;
        }

        if (newPassword !== confirmPassword) {
            showAlertModal('错误', '新密码与确认密码不一致', 'error');
            return;
        }

        try {
            const token = localStorage.getItem('authToken');
            const response = await fetch('/api/user/change-password', {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    current_password: currentPassword,
                    new_password: newPassword,
                    confirm_password: confirmPassword
                })
            });

            const result = await response.json();
            
            if (result.success) {
                showAlertModal('成功', '密码修改成功', 'success');
                // 清空密码字段
                $('#current-password').value = '';
                $('#new-password').value = '';
                $('#confirm-password').value = '';
            } else {
                showAlertModal('错误', result.message || '密码修改失败', 'error');
            }
        } catch (error) {
            console.error('修改密码失败:', error);
            showAlertModal('错误', '网络错误，请重试', 'error');
        }
    }

    // ---------------------- 工具函数（整合双方通用工具） ----------------------
    function $id(id) { return document.getElementById(id); }
    
    function safeAddEvent(id, evt, handler) {
        const el = $id(id);
        if (el) el.addEventListener(evt, handler);
    }
    
    function formatDateTime(date) {
        return date.toLocaleString('zh-CN', { 
            year: 'numeric', 
            month: '2-digit', 
            day: '2-digit', 
            hour: '2-digit', 
            minute: '2-digit', 
            second: '2-digit' 
        }).replace(/\//g, '-');
    }
    
    function setDefaultDate() {
        const today = new Date().toISOString().split('T')[0];
        const datePicker = $id('date-picker');
        if (datePicker) {
            datePicker.value = today;
            datePicker.max = today;
            datePicker.min = '2025-01-01';
            $id('display-date').textContent = today;
        }
    }

    // ---------------------- API接口统一封装（整合双方接口） ----------------------
    const API = {
        // 鲲鹏9.4原有API
        overview: {
            getStats: async function() {
                try {
                    const response = await fetch('/api/overview/stats');
                    return await response.json();
                } catch (error) {
                    console.error('获取概览统计数据失败:', error);
                    return {
                        accuracy_rate: 98.5,
                        accuracy_trend: '+2.3%',
                        production_lines: 8,
                        active_lines: 7,
                        operators_count: 42,
                        on_duty: 36,
                        daily_qualified: 12583,
                        qualified_rate: 98.2
                    };
                }
            }
        },
        
        schedule: {
            update: async function(ageDistribution) {
                try {
                    const response = await fetch('/api/schedule/update', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ age_distribution: ageDistribution })
                    });
                    return await response.json();
                } catch (error) {
                    console.error('更新排班配置失败:', error);
                    return { error: error.message };
                }
            },
            checkStatus: async function() {
                try {
                    const response = await fetch('/api/schedule/status');
                    return await response.json();
                } catch (error) {
                    console.error('检查排班状态失败:', error);
                    return { error: error.message };
                }
            },
            getResult1: async function() {
                try {
                    const response = await fetch('/api/schedule/result1');
                    return await response.json();
                } catch (error) {
                    console.error('获取排班结果1失败:', error);
                    return { error: error.message };
                }
            },
            getResult2: async function() {
                try {
                    const response = await fetch('/api/schedule/result2');
                    return await response.json();
                } catch (error) {
                    console.error('获取排班结果2失败:', error);
                    return { error: error.message };
                }
            },
            download: function(type) {
                window.open(`/download/${type}`, '_blank');
            }
        },
        
        settings: {
            save: async function(settings) {
                try {
                    const response = await fetch('/api/settings/save', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(settings)
                    });
                    return await response.json();
                } catch (error) {
                    console.error('保存系统设置失败:', error);
                    return { error: error.message };
                }
            },
            get: async function() {
                try {
                    const response = await fetch('/api/settings/get');
                    return await response.json();
                } catch (error) {
                    console.error('获取系统设置失败:', error);
                    return { error: error.message };
                }
            }
        },
        
        user: {
            updateProfile: async function(profile) {
                try {
                    const response = await fetch('/api/user/update-profile', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(profile)
                    });
                    return await response.json();
                } catch (error) {
                    console.error('更新用户信息失败:', error);
                    return { error: error.message };
                }
            },
            changePassword: async function(passwordData) {
                try {
                    const response = await fetch('/api/user/change-password', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify(passwordData)
                    });
                    return await response.json();
                } catch (error) {
                    console.error('修改密码失败:', error);
                    return { error: error.message };
                }
            }
        },
        
        // index引入的历史故障查询API
        faultQuery: {
            fetchData: async function(line, date) {
                try {
                    const apiUrl = new URL('http://localhost:5000/api/latest-data');
                    apiUrl.searchParams.append('line', line);
                    apiUrl.searchParams.append('date', date);
                    const response = await fetch(apiUrl.toString());
                    if (!response.ok) throw new Error(`状态码：${response.status}`);
                    return await response.json();
                } catch (error) {
                    console.error('获取历史故障数据失败:', error);
                    return { success: false, message: error.message };
                }
            },
            clearCache: async function(line) {
                try {
                    const apiUrl = new URL('http://localhost:5000/api/clear-cache');
                    if (line) apiUrl.searchParams.append('line', line);
                    const response = await fetch(apiUrl.toString());
                    if (!response.ok) throw new Error(`状态码：${response.status}`);
                    return await response.json();
                } catch (error) {
                    console.error('清空历史缓存失败:', error);
                    return { success: false, message: error.message };
                }
            }
        },
        
        // index引入的实时监测API
        realtime: {
            control: async function(line, action) {
                try {
                    const apiUrl = new URL('http://localhost:5000/api/realtime-monitor');
                    apiUrl.searchParams.append('line', line);
                    apiUrl.searchParams.append('action', action);
                    const response = await fetch(apiUrl.toString());
                    if (!response.ok) throw new Error(`状态码：${response.status}`);
                    return await response.json();
                } catch (error) {
                    console.error('实时监测控制失败:', error);
                    return { success: false, message: error.message };
                }
            },
            fetchStatus: async function(line) {
                try {
                    const apiUrl = new URL('http://localhost:5000/api/realtime-monitor');
                    apiUrl.searchParams.append('line', line);
                    apiUrl.searchParams.append('action', 'status');
                    const response = await fetch(apiUrl.toString());
                    if (!response.ok) throw new Error(`状态码：${response.status}`);
                    return await response.json();
                } catch (error) {
                    console.error('获取实时状态失败:', error);
                    return { success: false, message: error.message };
                }
            }
        }
    };

    // ---------------------- 鲲鹏9.4原有功能实现 ----------------------
    // 页面加载初始化
    window.addEventListener('DOMContentLoaded', () => {
        // 基础初始化
        bindBaseEventListeners();
        initWebSocket();
        initNavToggle();
        initThemeToggle();
        setDefaultDate();
        
        // 模块初始化
        loadOverviewData();
        initCharts();
        
        // 窗口resize处理
        window.addEventListener('resize', handleWindowResize);
        window.dispatchEvent(new Event('resize'));
    });

    // 加载系统概览数据（仅保留4个核心模块）
    async function loadOverviewData() {
        try {
            const stats = await API.overview.getStats();
            updateOverviewStats(stats);
        } catch (error) {
            console.error('加载概览数据失败:', error);
        }
    }

    // 更新概览统计卡片
    function updateOverviewStats(stats) {
        $id('accuracy-rate').textContent = stats.accuracy_rate + '%';
        $id('accuracy-trend').textContent = '较上月 ' + stats.accuracy_trend;
        $id('production-lines').textContent = stats.production_lines;
        $id('active-lines').innerHTML = `正常运行: <span class="font-medium text-neutral-600">${stats.active_lines}</span>/${stats.production_lines}`;
        $id('operators-count').textContent = stats.operators_count;
        $id('on-duty').innerHTML = `在岗: <span class="font-medium text-neutral-600">${stats.on_duty}</span>/${stats.operators_count}`;
        $id('daily-qualified').textContent = stats.daily_qualified.toLocaleString();
        $id('qualified-rate').innerHTML = `合格率: <span class="font-medium text-neutral-600">${stats.qualified_rate}%</span>`;
    }

    // 初始化WebSocket（鲲鹏9.4原有）
    function initWebSocket() {
        try {
            socket = io.connect(window.location.origin);
            socket.on('connect', () => {
                console.log('[WebSocket] 连接成功');
            });
            socket.on('disconnect', () => {
                console.log('[WebSocket] 连接断开，正在重连...');
                setTimeout(initWebSocket, 3000);
            });
        } catch (error) {
            console.error('[WebSocket] 初始化失败:', error);
            setTimeout(initWebSocket, 3000);
        }
    }

    // 初始化主题切换（鲲鹏9.4原有）
    function initThemeToggle() {
        const themeSelect = $id('theme-select');
        const savedTheme = localStorage.getItem('theme') || 'light';
        themeSelect.value = savedTheme;
        applyTheme(savedTheme);

        themeSelect.addEventListener('change', (e) => {
            const theme = e.target.value;
            localStorage.setItem('theme', theme);
            applyTheme(theme);
        });

        if (savedTheme === 'auto') {
            const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
            prefersDark.addEventListener('change', (e) => {
                if (themeSelect.value === 'auto') {
                    applyTheme(e.matches ? 'dark' : 'light');
                }
            });
        }
    }

    // 应用主题（鲲鹏9.4原有）
    function applyTheme(theme) {
        if (theme === 'auto') {
            const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
            theme = prefersDark.matches ? 'dark' : 'light';
        }

        if (theme === 'dark') {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
    }

    // 侧边栏控制（鲲鹏9.4原有）
    function toggleGlobalSidebar() {
        const sidebar = $id('globalSidebar');
        const mainContent = $id('main-content');
        if (!sidebar || !mainContent) return;

        const isShow = sidebar.classList.toggle('-translate-x-full');
        if (window.innerWidth < 1024) {
            document.body.style.overflow = isShow ? '' : 'hidden';
        }

        if (window.innerWidth >= 1024) {
            mainContent.classList.toggle('ml-44', !isShow);
        } else {
            mainContent.classList.remove('ml-44');
        }
    }

    // 管理员下拉控制（鲲鹏9.4原有）
    function toggleAdminDropdown() {
        const menu = $id('adminDropdownMenu');
        if (!menu) return;

        const isShow = menu.classList.toggle('hidden');
        if (isShow) {
            const closeHandler = (e) => {
                if (!menu.contains(e.target) && !$id('adminDropdownBtn').contains(e.target)) {
                    menu.classList.add('hidden');
                    document.removeEventListener('click', closeHandler);
                }
            };
            document.addEventListener('click', closeHandler);
        }
    }

    // 页面导航切换（按需求排序）
    function initNavToggle() {
        document.addEventListener('click', (e) => {
            const link = e.target.closest('.sidebar-link');
            if (!link) return;
            e.preventDefault();

            // 导航样式切换
            document.querySelectorAll('.sidebar-link').forEach(el => {
                el.classList.remove('text-primary', 'bg-primary/5', 'font-medium');
                el.classList.add('text-neutral-600', 'hover:bg-neutral-100');
            });
            link.classList.add('text-primary', 'bg-primary/5', 'font-medium');

            // 页面切换
            const target = link.getAttribute('data-target');
            document.querySelectorAll('.subpage').forEach(p => p.classList.add('hidden'));
            const page = $id(target);
            if (page) page.classList.remove('hidden');

            // 模块专属初始化
            if (target === 'overview-page') loadOverviewData();
            if (target === 'schedule-page') loadScheduleData();
            if (target === 'analysis-page') initProductionAnalysis();
            if (target === 'fault-page') updateRealtimeStatusIndicator(); // 实时页面激活时更新状态

            // 移动端自动关闭侧边栏
            if (window.innerWidth < 1024) toggleGlobalSidebar();
        });

        // 顶部下拉菜单导航
        document.querySelectorAll('#adminDropdownMenu a').forEach(link => {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const target = link.getAttribute('data-target');
                if (!target) return;

                document.querySelectorAll('.subpage').forEach(p => p.classList.add('hidden'));
                const page = $id(target);
                if (page) page.classList.remove('hidden');

                $id('adminDropdownMenu').classList.add('hidden');
            });
        });
    }

    // 窗口resize处理
    function handleWindowResize() {
        const sidebar = $id('globalSidebar');
        const mainContent = $id('main-content');
        if (!sidebar || !mainContent) return;

        if (window.innerWidth >= 1024) {
            sidebar.classList.remove('-translate-x-full');
            mainContent.classList.add('ml-44');
            document.body.style.overflow = '';
        } else {
            if (sidebar.classList.contains('-translate-x-full')) {
                document.body.style.overflow = '';
            } else {
                document.body.style.overflow = 'hidden';
            }
            mainContent.classList.remove('ml-44');
        }

        // 刷新图表避免变形
        try {
            faultTypeChart?.resize();
            faultTrendChart?.resize();
            window.realtimeTrendChart?.resize();
        } catch (e) {}
    }

    // ---------------------- 排班优化模块功能（鲲鹏9.4原有） ----------------------
    function calculateTotal() {
        const age1 = parseInt($id('age1').value) || 0;
        const age2 = parseInt($id('age2').value) || 0;
        const age3 = parseInt($id('age3').value) || 0;
        const age4 = parseInt($id('age4').value) || 0;
        const age5 = parseInt($id('age5').value) || 0;
        const age6 = parseInt($id('age6').value) || 0;

        const total = age1 + age2 + age3 + age4 + age5 + age6;
        $id('total-workers').textContent = total;

        const messageEl = $id('config-message');
        if (total !== 42) {
            messageEl.textContent = `警告: 总人数应为42人，当前为${total}人`;
            messageEl.className = 'bg-alert/10 text-alert p-3 rounded-lg';
            messageEl.classList.remove('hidden');
            $id('btn-update').disabled = true;
        } else {
            messageEl.textContent = '配置正确，可以更新排班';
            messageEl.className = 'bg-secondary/10 text-secondary p-3 rounded-lg';
            messageEl.classList.remove('hidden');
            $id('btn-update').disabled = false;
        }

        return total;
    }

    async function updateSchedule() {
        const ageDistribution = {
            1: parseInt($id('age1').value),
            2: parseInt($id('age2').value),
            3: parseInt($id('age3').value),
            4: parseInt($id('age4').value),
            5: parseInt($id('age5').value),
            6: parseInt($id('age6').value)
        };

        const btnUpdate = $id('btn-update');
        const originalText = btnUpdate.textContent;

        try {
            btnUpdate.disabled = true;
            btnUpdate.textContent = '计算中...';

            const response = await API.schedule.update(ageDistribution);
            if (response.error) throw new Error(response.error);

            if (response.processing) {
                const messageEl = $id('config-message');
                messageEl.textContent = '排班计算中，这可能需要几分钟时间，请耐心等待...';
                messageEl.className = 'bg-info/10 text-info p-3 rounded-lg';
                checkScheduleStatus();
            }
        } catch (error) {
            const messageEl = $id('config-message');
            messageEl.textContent = '更新失败: ' + error.message;
            messageEl.className = 'bg-alert/10 text-alert p-3 rounded-lg';
            btnUpdate.disabled = false;
            btnUpdate.textContent = originalText;
        }
    }

    async function checkScheduleStatus() {
        try {
            const status = await API.schedule.checkStatus();
            const messageEl = $id('config-message');
            const btnUpdate = $id('btn-update');

            if (status.is_processing) {
                messageEl.textContent = '排班计算中，请耐心等待...';
                setTimeout(checkScheduleStatus, 3000);
            } else if (status.last_error) {
                messageEl.textContent = '计算失败: ' + status.last_error;
                messageEl.className = 'bg-alert/10 text-alert p-3 rounded-lg';
                btnUpdate.disabled = false;
                btnUpdate.textContent = '更新排班';
            } else {
                messageEl.textContent = '排班更新成功！正在刷新数据...';
                messageEl.className = 'bg-secondary/10 text-secondary p-3 rounded-lg';
                btnUpdate.disabled = false;
                btnUpdate.textContent = '更新排班';
                setTimeout(loadScheduleData, 1000);
            }
        } catch (error) {
            console.error('状态检查错误:', error);
            setTimeout(checkScheduleStatus, 3000);
        }
    }

    async function loadScheduleData() {
        try {
            const data1 = await API.schedule.getResult1();
            if (data1.error) throw new Error(data1.error);
            renderScheduleTable('table1', data1.columns, data1.data);

            const data2 = await API.schedule.getResult2();
            if (data2.error) throw new Error(data2.error);
            renderScheduleTable('table2', data2.columns, data2.data);

            $id('update-time').textContent = data1.last_updated || new Date().toLocaleString();
        } catch (error) {
            console.error('加载排班数据错误:', error);
        }
    }

    function renderScheduleTable(tableId, columns, data) {
        const headerRow = $id(`${tableId}-header`);
        const body = $id(`${tableId}-body`);

        headerRow.innerHTML = '';
        body.innerHTML = '';

        // 渲染表头
        columns.forEach(column => {
            const th = document.createElement('th');
            th.textContent = column;
            th.className = 'px-4 py-2 text-left text-xs font-medium text-neutral-400 uppercase tracking-wider';
            headerRow.appendChild(th);
        });

        // 渲染数据行
        data.forEach(rowData => {
            const tr = document.createElement('tr');
            rowData.forEach(cellData => {
                const td = document.createElement('td');
                td.textContent = cellData !== null ? cellData : '';
                td.className = 'px-4 py-2 text-sm';

                if (cellData === '早') td.className += ' text-primary font-medium';
                else if (cellData === '中') td.className += ' text-secondary font-medium';
                else if (cellData === '晚') td.className += ' text-alert font-medium';
                else if (cellData === '休') td.className += ' text-neutral-400';

                tr.appendChild(td);
            });
            body.appendChild(tr);
        });
    }

    function downloadScheduleFile(type) {
        API.schedule.download(type);
    }

   

    // ---------------------- 从index整合的故障日期查询模块功能 ----------------------
    // 初始化图表（故障类型+趋势）
    function initCharts() {
        // 故障类型分布图表
        const typeCtx = $id('fault-type-chart')?.getContext('2d');
        if (typeCtx) {
            faultTypeChart = new Chart(typeCtx, {
                type: 'doughnut',
                data: {
                    labels: [],
                    datasets: [{
                        data: [],
                        backgroundColor: [
                            '#007AFF', '#FF3B30', '#34C759', '#FF9500',
                            '#5856D6', '#AF52DE', '#FF2D55', '#00C7BE'
                        ],
                        borderWidth: 0,
                        hoverOffset: 5
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: { position: 'bottom', labels: { boxWidth: 10, padding: 12, font: { size: 11 }, color: '#6E6E73' } },
                        tooltip: {
                            backgroundColor: 'rgba(255,255,255,0.95)',
                            titleColor: '#3A3A3C',
                            bodyColor: '#6E6E73',
                            callbacks: {
                                label: (ctx) => `${ctx.label}: ${ctx.raw}次 (${Math.round((ctx.raw/ctx.dataset.data.reduce((a,b)=>a+b,0))*100)}%)`
                            }
                        }
                    },
                    cutout: '65%'
                }
            });
        }

        // 故障趋势图表
        const trendCtx = $id('fault-trend-chart')?.getContext('2d');
        if (trendCtx) {
            const hourLabels = Array.from({length:24}, (_,i)=>`${i.toString().padStart(2,'0')}:00`);
            faultTrendChart = new Chart(trendCtx, {
                type: 'line',
                data: {
                    labels: hourLabels,
                    datasets: [{
                        label: '故障次数',
                        data: Array(24).fill(0),
                        borderColor: '#007AFF',
                        backgroundColor: 'rgba(0,122,255,0.08)',
                        fill: true,
                        tension: 0.4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    scales: {
                        x: { grid: { display: false }, ticks: { color: '#6E6E73', font: { size: 10 } } },
                        y: { beginAtZero: true, grid: { color: '#F5F5F7' }, ticks: { color: '#6E6E73', font: { size: 10 } } }
                    },
                    plugins: { legend: { display: false } }
                }
            });
        }

        // 实时趋势图表
        const realtimeTrendCtx = $id('realtime-trend-chart')?.getContext('2d');
        if (realtimeTrendCtx) {
            const hourLabels = Array.from({length:24}, (_,i)=>`${i.toString().padStart(2,'0')}:00`);
            window.realtimeTrendChart = new Chart(realtimeTrendCtx, {
                type: 'line',
                data: {
                    labels: hourLabels,
                    datasets: [{
                        label: '实时故障次数',
                        data: Array(24).fill(0),
                        borderColor: '#FF3B30',
                        backgroundColor: 'rgba(255,59,48,0.08)',
                        fill: true,
                        tension: 0.4,
                        borderDash: realtimeModule.isRunning ? [] : [5,5]
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    scales: {
                        x: { grid: { display: false }, ticks: { color: '#6E6E73', font: { size: 10 } } },
                        y: { beginAtZero: true, grid: { color: '#F5F5F7' }, ticks: { color: '#6E6E73', font: { size: 10 } } }
                    },
                    plugins: { legend: { display: false } }
                }
            });
        }
    }

    // 加载历史故障数据
    async function fetchFaultData() {
        showLoadingState(true);
        try {
            const line = $id('line-select').value;
            const date = $id('date-picker').value;
            const cacheKey = `${line}-${date}`;

            // 优先读缓存
            const cached = dataCache.get(cacheKey);
            if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
                updateFaultUIWithData(cached.data);
                showLoadingState(false);
                return;
            }

            // 调用历史接口
            const result = await API.faultQuery.fetchData(line, date);
            if (!result.success) throw new Error(result.message);

            // 更新缓存
            dataCache.set(cacheKey, { data: result, timestamp: Date.now() });
            updateFaultUIWithData(result);
            $id('last-update-time').textContent = result.timestamp || new Date().toLocaleString();
        } catch (error) {
            showAlertModal('获取数据失败', error.message || '未知错误', 'error');
        } finally {
            showLoadingState(false);
        }
    }

    // 清空历史缓存
    async function clearFaultCache() {
        showLoadingState(true);
        try {
            const line = $id('line-select').value;
            const result = await API.faultQuery.clearCache(line);
            if (!result.success) throw new Error(result.message);

            // 清理前端缓存
            if (line) {
                for (const key of dataCache.keys()) {
                    if (key.startsWith(`${line}-`)) dataCache.delete(key);
                }
            } else {
                dataCache.clear();
            }

            await fetchFaultData();
            showAlertModal('操作成功', result.message || '缓存已清空', 'success');
        } catch (error) {
            showAlertModal('操作失败', error.message || '清空失败', 'error');
        } finally {
            showLoadingState(false);
        }
    }

    // 更新故障查询UI
    function updateFaultUIWithData(data) {
        if (!data.success) return;
        const activeFaults = data.active_faults || [];
        const faultHistory = data.fault_history || [];
        const trendData = data.trend_data || { labels: [], values: [] };
        const batchInfo = data.batch_info || { processed_rows: 0 };

        updateFaultOverviewCards(activeFaults, faultHistory, trendData, batchInfo);
        updateActiveFaultsList(activeFaults);
        updateFaultHistoryTable(faultHistory);
        updateFaultTrendChart(trendData);
        $id('processed-rows').textContent = batchInfo.processed_rows.toLocaleString();
    }

    // 更新故障概览卡片
    function updateFaultOverviewCards(activeFaults, faultHistory, trendData, batchInfo) {
        const overallStatus = $id('overall-status');
        const statusIndicator = $id('status-indicator');

        // 整体状态
        if (activeFaults.length > 0) {
            overallStatus.textContent = '故障';
            overallStatus.className = 'text-2xl font-semibold text-alert mt-1 status-pulse';
            statusIndicator.className = 'w-10 h-10 rounded-full bg-alert/10 flex items-center justify-center';
            statusIndicator.innerHTML = '<i class="fa fa-exclamation-circle text-alert"></i>';
        } else {
            overallStatus.textContent = '正常';
            overallStatus.className = 'text-2xl font-semibold text-secondary mt-1';
            statusIndicator.className = 'w-10 h-10 rounded-full bg-secondary/10 flex items-center justify-center';
            statusIndicator.innerHTML = '<i class="fa fa-check text-secondary"></i>';
        }

        // 活跃故障数
        $id('active-fault-count').textContent = activeFaults.length;

        // 最近故障
        const latestFaultEl = $id('latest-fault-info');
        if (faultHistory.length > 0) {
            const sorted = [...faultHistory].sort((a,b)=>new Date(b.start_time)-new Date(a.start_time));
            const latest = sorted[0];
            const timePart = latest.start_time.split(' ')[1];
            latestFaultEl.textContent = `${latest.model_key} (${timePart})`;
        } else {
            latestFaultEl.textContent = '无记录';
        }

        // 故障总数
        $id('total-fault-count').textContent = faultHistory.length;

        // 高峰时段
        const values = trendData.values || [];
        if (values.length > 0) {
            const maxCount = Math.max(...values);
            const peakIndex = values.indexOf(maxCount);
            $id('peak-time').textContent = `${peakIndex.toString().padStart(2,'0')}:00`;
            $id('peak-fault-count').textContent = maxCount;
        } else {
            $id('peak-time').textContent = '--:--';
            $id('peak-fault-count').textContent = '0';
        }

        $id('display-date').textContent = $id('date-picker').value;
    }

    // 更新活跃故障列表
    function updateActiveFaultsList(activeFaults) {
        const container = $id('active-faults-container');
        const emptyEl = $id('active-faults-empty');
        const loadingEl = $id('active-faults-loading');

        emptyEl.classList.add('hidden');
        loadingEl.classList.remove('hidden');

        setTimeout(() => {
            if (activeFaults.length === 0) {
                emptyEl.classList.remove('hidden');
                loadingEl.classList.add('hidden');
                return;
            }

            container.innerHTML = '';
            activeFaults.forEach(fault => {
                const faultEl = document.createElement('div');
                faultEl.className = 'border-l-4 border-alert bg-alert/5 p-3 rounded-r hover:bg-alert/10 transition-all cursor-pointer btn-press';
                faultEl.onclick = () => showFaultDetail(fault.id, fullFaultHistory);
                faultEl.innerHTML = `
                    <div class="flex justify-between items-start">
                        <h4 class="font-medium text-neutral-600">${fault.model_key}</h4>
                        <span class="w-2 h-2 rounded-full bg-alert status-pulse"></span>
                    </div>
                    <p class="text-xs text-neutral-400 mt-1">开始时间: ${fault.start_time}</p>
                    <p class="text-xs text-neutral-400 mt-0.5">持续时间: ${(fault.duration || 0).toFixed(1)} 秒</p>
                `;
                container.appendChild(faultEl);
            });
            loadingEl.classList.add('hidden');
        }, 300);
    }

    // 更新故障历史表格
    function updateFaultHistoryTable(historyData) {
        fullFaultHistory = historyData;
        const tableBody = $id('history-table-body');
        const emptyRow = $id('history-empty-row');
        const loadingRow = $id('history-loading-row');
        const prevBtn = $id('prev-page-btn');
        const nextBtn = $id('next-page-btn');
        const currentPageEl = $id('current-page');
        const totalPagesEl = $id('total-pages');

        emptyRow.classList.add('hidden');
        loadingRow.classList.remove('hidden');

        const totalItems = historyData.length;
        const totalPages = Math.max(1, Math.ceil(totalItems / PAGE_SIZE));
        currentPage = Math.min(Math.max(1, currentPage), totalPages);

        setTimeout(() => {
            if (totalItems === 0) {
                emptyRow.classList.remove('hidden');
                loadingRow.classList.add('hidden');
                prevBtn.disabled = true;
                nextBtn.disabled = true;
                currentPageEl.textContent = '1';
                totalPagesEl.textContent = '1';
                return;
            }

            while (tableBody.children.length > 2) {
                tableBody.removeChild(tableBody.lastChild);
            }
            emptyRow.classList.add('hidden');
            loadingRow.classList.add('hidden');

            const startIdx = (currentPage - 1) * PAGE_SIZE;
            const endIdx = Math.min(startIdx + PAGE_SIZE, totalItems);
            const currentPageData = historyData.slice(startIdx, endIdx);

            currentPageData.forEach(fault => {
                const row = document.createElement('tr');
                row.className = 'hover:bg-neutral-50 transition-colors';
                row.innerHTML = `
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${fault.id}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${fault.model_key}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">${fault.start_time}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">
                        ${fault.end_time ? fault.end_time : '<span class="text-alert">未结束</span>'}
                    </td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">
                        ${(fault.duration || 0).toFixed(1)} 秒
                    </td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm">
                        <button class="btn-press text-primary hover:text-primary/80 transition-colors" onclick="showFaultDetail(${fault.id}, fullFaultHistory)">
                            <i class="fa fa-eye mr-1"></i>详情
                        </button>
                    </td>
                `;
                tableBody.appendChild(row);
            });

            prevBtn.disabled = currentPage === 1;
            nextBtn.disabled = currentPage === totalPages;
            currentPageEl.textContent = currentPage;
            totalPagesEl.textContent = totalPages;
        }, 300);
    }

    // 更新故障趋势图表
    function updateFaultTrendChart(trendData) {
        const { labels = [], values = [] } = trendData;
        const noDataEl = $id('trend-chart-no-data');
        const loadingEl = $id('trend-chart-loading');

        noDataEl.classList.add('hidden');
        loadingEl.classList.remove('hidden');

        setTimeout(() => {
            const hasData = values.some(v => v > 0);
            if (!hasData) {
                noDataEl.classList.remove('hidden');
                loadingEl.classList.add('hidden');
                return;
            }

            faultTrendChart.data.labels = labels;
            faultTrendChart.data.datasets[0].data = values;
            faultTrendChart.update();

            noDataEl.classList.add('hidden');
            loadingEl.classList.add('hidden');
        }, 300);
    }

    // 刷新故障类型图表
    function refreshFaultTypeChart() {
        const noDataEl = $id('type-chart-no-data');
        const loadingEl = $id('type-chart-loading');

        noDataEl.classList.add('hidden');
        loadingEl.classList.remove('hidden');

        setTimeout(() => {
            const typeCount = {};
            fullFaultHistory.forEach(fault => {
                typeCount[fault.model_key] = (typeCount[fault.model_key] || 0) + 1;
            });

            const types = Object.keys(typeCount);
            const counts = Object.values(typeCount);

            if (types.length === 0) {
                noDataEl.classList.remove('hidden');
                loadingEl.classList.add('hidden');
                return;
            }

            faultTypeChart.data.labels = types;
            faultTypeChart.data.datasets[0].data = counts;
            faultTypeChart.update();

            noDataEl.classList.add('hidden');
            loadingEl.classList.add('hidden');
        }, 300);
    }

    // 分页切换
    function changePage(step) {
        const totalPages = Math.max(1, Math.ceil(fullFaultHistory.length / PAGE_SIZE));
        const newPage = currentPage + step;
        if (newPage < 1 || newPage > totalPages) return;

        currentPage = newPage;
        updateFaultHistoryTable(fullFaultHistory);
        $id('history-table-body').scrollIntoView({ behavior: 'smooth', block: 'start' });
    }

    // 显示加载状态
    function showLoadingState(show) {
        const refreshBtn = $id('refresh-btn');
        const clearCacheBtn = $id('clear-cache-btn');
        const refreshIcon = $id('refresh-icon');
        const loadingStatus = $id('loading-status');

        if (show) {
            refreshBtn.disabled = true;
            clearCacheBtn.disabled = true;
            refreshIcon.classList.add('spin-slow');
            loadingStatus.classList.remove('hidden');
        } else {
            if (hasInitiatedDataLoad) {
                refreshBtn.disabled = false;
                clearCacheBtn.disabled = false;
            }
            refreshIcon.classList.remove('spin-slow');
            loadingStatus.classList.add('hidden');
        }
    }

    // ---------------------- 从index整合的实时监测模块功能 ----------------------
    // 控制实时监测
    async function controlRealtimeMonitor(action) {
        const line = $id('realtime-line-select').value;
        const startBtn = $id('start-monitor-btn');
        const stopBtn = $id('stop-monitor-btn');
        const loadingStatus = $id('realtime-loading-status');

        startBtn.disabled = true;
        stopBtn.disabled = true;
        loadingStatus.classList.remove('hidden');

        try {
            const result = await API.realtime.control(line, action);
            if (!result.success) throw new Error(result.message);

            // 更新实时状态
            realtimeModule.isRunning = result.is_running;
            if (realtimeModule.isRunning) {
                // 启动定时器
                if (realtimeModule.monitorInterval) clearInterval(realtimeModule.monitorInterval);
                realtimeModule.monitorInterval = setInterval(() => fetchRealtimeData(), 3000);
                fetchRealtimeData(); // 立即拉取
                startBtn.disabled = true;
                stopBtn.disabled = false;
                showAlertModal('操作成功', `${line} 实时监测已启动（3秒/次）`, 'success');
            } else {
                // 停止定时器
                if (realtimeModule.monitorInterval) {
                    clearInterval(realtimeModule.monitorInterval);
                    realtimeModule.monitorInterval = null;
                }
                startBtn.disabled = false;
                stopBtn.disabled = true;
                showAlertModal('操作成功', `${line} 实时监测已停止`, 'success');
            }

            updateRealtimeStatusIndicator();
            updateRealtimeTrendChartStyle();
        } catch (error) {
            showAlertModal('操作失败', error.message || '控制异常', 'error');
            startBtn.disabled = realtimeModule.isRunning;
            stopBtn.disabled = !realtimeModule.isRunning;
        } finally {
            loadingStatus.classList.add('hidden');
        }
    }

    // 获取实时数据
    async function fetchRealtimeData() {
        const line = $id('realtime-line-select').value;
        const trendNoDataEl = $id('realtime-trend-no-data');
        const trendLoadingEl = $id('realtime-trend-loading');

        try {
            const result = await API.realtime.fetchStatus(line);
            if (!result.success) throw new Error(result.message);

            // 更新基础信息
            $id('realtime-last-sync').textContent = result.timestamp || formatDateTime(new Date());
            $id('realtime-trend-update').textContent = result.timestamp || formatDateTime(new Date());
            $id('realtime-data-source').textContent = `${line}生产线实时数据流`;
            $id('realtime-display-line').textContent = `${line}生产线`;

            // 存储活跃故障
            realtimeModule.activeFaults = result.active_faults || [];

            // 更新各组件
            updateRealtimeStatusOverview(result);
            updateRealtimeActiveFaults(result.active_faults || []);
            updateRealtimeHistory(result.recent_history || []);
            updateRealtimeTrendChart(result.today_trend || { labels: [], values: [] });
            updateRealtimeDetail(result.latest_data || null);
            updateRealtimeAlertBadge();

            trendNoDataEl.classList.add('hidden');
            trendLoadingEl.classList.add('hidden');
        } catch (error) {
            console.error('拉取实时数据失败:', error);
            if (realtimeModule.isRunning) {
                trendNoDataEl.classList.remove('hidden');
                trendNoDataEl.innerHTML = `
                    <i class="fa fa-area-chart text-neutral-200 text-2xl mb-2"></i>
                    <p class="text-neutral-400 text-sm">实时监测已启动，暂无故障数据</p>
                `;
            }
            trendLoadingEl.classList.add('hidden');
        }
    }

    // 更新实时状态概览
    function updateRealtimeStatusOverview(result) {
        const activeFaults = result.active_faults || [];
        const recentHistory = result.recent_history || [];

        // 运行状态
        const runStatusEl = $id('realtime-run-status');
        if (activeFaults.length > 0) {
            runStatusEl.textContent = '故障';
            runStatusEl.className = 'text-sm font-medium text-alert';
        } else {
            runStatusEl.textContent = '正常';
            runStatusEl.className = 'text-sm font-medium text-secondary';
        }

        // 活跃故障数
        $id('realtime-active-count').textContent = activeFaults.length;
        $id('realtime-active-badge').textContent = activeFaults.length;

        // 今日故障总数
        const todayDate = new Date().toISOString().split('T')[0];
        const todayFaultCount = recentHistory.filter(f => f.start_time.split(' ')[0] === todayDate).length;
        $id('realtime-total-count').textContent = todayFaultCount;

        // 最新故障
        const latestFaultEl = $id('realtime-latest-fault');
        if (recentHistory.length > 0) {
            const latest = recentHistory[0];
            const timePart = latest.start_time.split(' ')[1];
            latestFaultEl.textContent = `${latest.model_key}（${timePart}）`;
            latestFaultEl.className = 'text-sm text-neutral-600';
        } else {
            latestFaultEl.textContent = '无记录';
            latestFaultEl.className = 'text-sm text-neutral-400';
        }
    }

    // 更新实时活跃故障列表
    function updateRealtimeActiveFaults(activeFaults) {
        const container = $id('realtime-active-container');
        const emptyEl = $id('realtime-active-empty');
        const loadingEl = $id('realtime-active-loading');

        emptyEl.classList.add('hidden');
        loadingEl.classList.remove('hidden');

        setTimeout(() => {
            if (activeFaults.length === 0) {
                emptyEl.classList.remove('hidden');
                loadingEl.classList.add('hidden');
                return;
            }

            container.innerHTML = '';
            activeFaults.forEach(fault => {
                const faultEl = document.createElement('div');
                faultEl.className = 'border-l-4 border-alert bg-alert/5 p-3 rounded-r hover:bg-alert/10 transition-all cursor-pointer btn-press blink-alert';
                faultEl.onclick = () => showFaultDetail(fault.id, activeFaults);
                faultEl.innerHTML = `
                    <div class="flex justify-between items-start">
                        <h4 class="font-medium text-neutral-600">${fault.model_key}</h4>
                        <span class="w-2 h-2 rounded-full bg-alert status-pulse"></span>
                    </div>
                    <p class="text-xs text-neutral-400 mt-1">开始时间: ${fault.start_time}</p>
                    <p class="text-xs text-neutral-400 mt-0.5">持续时间: ${(fault.duration || 0).toFixed(1)} 秒</p>
                    <div class="mt-2 text-xs text-neutral-500">
                        <p>物料推送数: ${fault.raw_features?.['物料推送数'] || 0}</p>
                        <p>放置容器数: ${fault.raw_features?.['放置容器数'] || 0}</p>
                    </div>
                `;
                container.appendChild(faultEl);
            });
            loadingEl.classList.add('hidden');
        }, 200);
    }

    // 更新实时历史记录
    function updateRealtimeHistory(recentHistory) {
        const tableBody = $id('realtime-history-body');
        const emptyRow = $id('realtime-history-empty-row');
        const loadingRow = $id('realtime-history-loading-row');

        emptyRow.classList.add('hidden');
        loadingRow.classList.remove('hidden');

        setTimeout(() => {
            if (recentHistory.length === 0) {
                emptyRow.classList.remove('hidden');
                loadingRow.classList.add('hidden');
                return;
            }

            while (tableBody.children.length > 2) {
                tableBody.removeChild(tableBody.lastChild);
            }
            emptyRow.classList.add('hidden');
            loadingRow.classList.add('hidden');

            recentHistory.forEach(fault => {
                const row = document.createElement('tr');
                row.className = 'hover:bg-neutral-50 transition-colors';
                row.innerHTML = `
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${fault.id}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${fault.model_key}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">${fault.start_time}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">
                        ${fault.end_time ? fault.end_time : '<span class="text-alert">未结束</span>'}
                    </td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">
                        ${(fault.duration || 0).toFixed(1)} 秒
                    </td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm">
                        <span class="px-2 py-0.5 rounded-full text-xs ${fault.is_active ? 'bg-alert/10 text-alert' : 'bg-secondary/10 text-secondary'}">
                            ${fault.is_active ? '活跃中' : '已解除'}
                        </span>
                    </td>
                `;
                tableBody.appendChild(row);
            });
        }, 200);
    }

    // 更新实时趋势图表
    function updateRealtimeTrendChart(trendData) {
        const { labels = [], values = [] } = trendData;
        const trendNoDataEl = $id('realtime-trend-no-data');
        const realtimeTrendChart = window.realtimeTrendChart;

        if (!realtimeTrendChart) return;

        realtimeTrendChart.data.labels = labels;
        realtimeTrendChart.data.datasets[0].data = values;
        realtimeTrendChart.update();

        const hasData = values.some(v => v > 0);
        if (realtimeModule.isRunning && !hasData) {
            trendNoDataEl.classList.remove('hidden');
            trendNoDataEl.innerHTML = `
                <i class="fa fa-area-chart text-neutral-200 text-2xl mb-2"></i>
                <p class="text-neutral-400 text-sm">实时监测已启动，暂无故障数据</p>
            `;
        } else if (!realtimeModule.isRunning) {
            trendNoDataEl.classList.remove('hidden');
            trendNoDataEl.innerHTML = `
                <i class="fa fa-area-chart text-neutral-200 text-2xl mb-2"></i>
                <p class="text-neutral-400 text-sm">未启动实时监测或暂无数据</p>
            `;
        } else {
            trendNoDataEl.classList.add('hidden');
        }
    }

    // 更新实时趋势图表样式
    function updateRealtimeTrendChartStyle() {
        const realtimeTrendChart = window.realtimeTrendChart;
        if (!realtimeTrendChart) return;
        realtimeTrendChart.data.datasets[0].borderDash = realtimeModule.isRunning ? [] : [5,5];
        realtimeTrendChart.update();
    }

    // 更新实时数据详情
    function updateRealtimeDetail(latestData) {
        const tableBody = $id('realtime-detail-body');
        const emptyRow = $id('realtime-detail-empty-row');
        const loadingRow = $id('realtime-detail-loading-row');

        emptyRow.classList.add('hidden');
        loadingRow.classList.remove('hidden');

        setTimeout(() => {
            // 添加最新数据（去重）
            if (latestData && latestData.predictions) {
                const exists = realtimeModule.detailData.some(item => item.datetime === latestData.datetime);
                if (!exists) {
                    realtimeModule.detailData.unshift(latestData);
                    // 限制记录数
                    if (realtimeModule.detailData.length > realtimeModule.MAX_DETAIL_RECORDS) {
                        realtimeModule.detailData.pop();
                    }
                }
            }

            if (realtimeModule.detailData.length === 0) {
                emptyRow.classList.remove('hidden');
                loadingRow.classList.add('hidden');
                return;
            }

            while (tableBody.children.length > 2) {
                tableBody.removeChild(tableBody.lastChild);
            }
            emptyRow.classList.add('hidden');
            loadingRow.classList.add('hidden');

            realtimeModule.detailData.forEach(data => {
                const firstPred = data.predictions[0] || {};
                const row = document.createElement('tr');
                row.className = 'hover:bg-neutral-50 transition-colors';
                row.innerHTML = `
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-400">${data.datetime}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${firstPred.model_key || '未知'}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm">
                        <span class="px-2 py-0.5 rounded-full text-xs ${firstPred.value === 1 ? 'bg-alert/10 text-alert' : 'bg-secondary/10 text-secondary'}">
                            ${firstPred.status || '未知'}
                        </span>
                    </td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${firstPred.raw_features?.['物料推送数'] || 0}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${firstPred.raw_features?.['物料待抓取数'] || 0}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${firstPred.raw_features?.['放置容器数'] || 0}</td>
                    <td class="px-4 py-3 whitespace-nowrap text-sm text-neutral-600">${firstPred.raw_features?.['容器上传检测数'] || 0}</td>
                `;
                tableBody.appendChild(row);
            });
        }, 200);
    }

    // 更新实时状态提示
    function updateRealtimeStatusIndicator() {
        const indicatorEl = $id('realtime-status-indicator');
        const statusDotEl = $id('realtime-status-dot');
        const statusTextEl = $id('realtime-status-text');

        if (!indicatorEl) return;

        if (realtimeModule.isRunning) {
            statusDotEl.className = 'inline-block w-2 h-2 rounded-full bg-secondary status-pulse';
            statusTextEl.textContent = '实时监测运行中';
            statusTextEl.className = 'text-secondary';
        } else {
            statusDotEl.className = 'inline-block w-2 h-2 rounded-full bg-neutral-300';
            statusTextEl.textContent = '实时监测未启动';
            statusTextEl.className = 'text-neutral-500';
        }
    }

    // 更新实时告警徽章
    function updateRealtimeAlertBadge() {
        const badgeEl = $id('realtime-alert-badge');
        const activeCount = realtimeModule.activeFaults.length;

        if (activeCount > 0) {
            badgeEl.classList.remove('hidden');
            badgeEl.textContent = activeCount;
        } else {
            badgeEl.classList.add('hidden');
        }
    }

    // ---------------------- 弹窗控制（整合双方逻辑） ----------------------
    function showFaultDetail(faultId, faultList) {
        const modal = $id('fault-detail-modal');
        const modalWrapper = $id('modal-content-wrapper');
        const modalTitle = $id('modal-title');
        const modalBody = $id('modal-body');

        const fault = faultList.find(f => f.id === faultId);
        if (!fault) {
            showAlertModal('数据错误', '未找到指定故障记录', 'error');
            return;
        }

        // 动态生成详情内容
        modalTitle.textContent = `故障详情 - ${fault.model_key}`;
        modalBody.innerHTML = `
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">故障ID</p>
                    <p class="text-sm font-medium text-neutral-600">${fault.id}</p>
                </div>
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">所属生产线</p>
                    <p class="text-sm font-medium text-neutral-600">${fault.production_line}</p>
                </div>
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">开始时间</p>
                    <p class="text-sm font-medium text-neutral-600">${fault.start_time}</p>
                </div>
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">结束时间</p>
                    <p class="text-sm font-medium ${fault.end_time ? 'text-neutral-600' : 'text-alert'}">
                        ${fault.end_time || '当前仍活跃'}
                    </p>
                </div>
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">持续时间</p>
                    <p class="text-sm font-medium text-neutral-600">${(fault.duration || 0).toFixed(1)} 秒</p>
                </div>
                <div class="space-y-1">
                    <p class="text-xs text-neutral-400">故障状态</p>
                    <p class="text-sm font-medium ${fault.is_active ? 'text-alert' : 'text-secondary'}">
                        ${fault.is_active ? '活跃中' : '已解除'}
                    </p>
                </div>
            </div>
            ${fault.raw_features ? `
            <div class="mt-4 pt-4 border-t border-neutral-100">
                <p class="text-xs text-neutral-400 mb-2">关联生产数据</p>
                <div class="grid grid-cols-2 sm:grid-cols-4 gap-3">
                    <div class="bg-neutral-50 p-2 rounded-md text-center">
                        <p class="text-xs text-neutral-400">物料推送数</p>
                        <p class="text-sm font-medium text-neutral-600">${fault.raw_features['物料推送数'] || 0}</p>
                    </div>
                    <div class="bg-neutral-50 p-2 rounded-md text-center">
                        <p class="text-xs text-neutral-400">物料待抓取数</p>
                        <p class="text-sm font-medium text-neutral-600">${fault.raw_features['物料待抓取数'] || 0}</p>
                    </div>
                    <div class="bg-neutral-50 p-2 rounded-md text-center">
                        <p class="text-xs text-neutral-400">放置容器数</p><p class="text-sm font-medium text-neutral-600">${fault.raw_features['放置容器数'] || 0}</p>
                    </div>
                    <div class="bg-neutral-50 p-2 rounded-md text-center">
                        <p class="text-xs text-neutral-400">容器上传检测数</p>
                        <p class="text-sm font-medium text-neutral-600">${fault.raw_features['容器上传检测数'] || 0}</p>
                    </div>
                </div>
            </div>
            ` : ''}
            <div class="mt-4 pt-4 border-t border-neutral-100">
                <p class="text-xs text-neutral-400 mb-2">故障说明</p>
                <div class="bg-neutral-50 p-3 rounded-md text-sm text-neutral-600">
                    ${getFaultDescription(fault.model_key)}
                </div>
            </div>
        `;

        // 显示弹窗
        modal.classList.remove('hidden');
        document.body.style.overflow = 'hidden';
        setTimeout(() => {
            modalWrapper.classList.remove('scale-95', 'opacity-0');
            modalWrapper.classList.add('scale-100', 'opacity-100');
        }, 10);
    }

    // 关闭故障详情弹窗
    function closeFaultModal() {
        const modal = $id('fault-detail-modal');
        const modalWrapper = $id('modal-content-wrapper');
        
        modalWrapper.classList.remove('scale-100', 'opacity-100');
        modalWrapper.classList.add('scale-95', 'opacity-0');
        setTimeout(() => {
            modal.classList.add('hidden');
            document.body.style.overflow = '';
        }, 200);
    }

    // 显示提示弹窗
    function showAlertModal(title, message, type = 'info') {
        const modal = $id('alert-modal');
        const alertTitle = $id('alert-title');
        const alertMessage = $id('alert-message');
        const alertIcon = $id('alert-icon');
        const alertIconContainer = $id('alert-icon-container');
        
        const config = {
            success: { icon: 'check-circle', color: 'text-secondary', bg: 'bg-secondary/10' },
            error: { icon: 'exclamation-circle', color: 'text-alert', bg: 'bg-alert/10' },
            info: { icon: 'info-circle', color: 'text-primary', bg: 'bg-primary/10' }
        };
        const { icon, color, bg } = config[type] || config.info;
        
        alertTitle.textContent = title;
        alertMessage.textContent = message;
        alertIcon.className = `fa fa-${icon} ${color}`;
        alertIconContainer.className = `w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${bg}`;
        
        modal.classList.remove('hidden');
        document.body.style.overflow = 'hidden';
    }

    // 关闭提示弹窗
    function closeAlertModal() {
        const modal = $id('alert-modal');
        modal.classList.add('hidden');
        document.body.style.overflow = '';
    }

    // 获取故障说明
    function getFaultDescription(modelKey) {
        const descMap = {
            '1001故障': '物料推送气缸推送与收回状态异常（两者相等），可能导致物料无法正常推送，影响后续工序',
            '2001故障': '物料推送数与待抓取数不匹配，提示物料检测环节存在计数偏差或物料丢失风险',
            '4001故障': '放置容器数与容器上传检测数不匹配，可能存在容器定位偏差或检测传感器故障',
            '4002故障': '填装定位器固定与放开状态异常（两者相等），定位功能失效，将导致填装位置偏差',
            '4003故障': '物料待抓取数与实际抓取数不匹配，提示填装环节物料抓取机构异常或物料卡滞',
            '5001故障': '填装数与加盖检测数不匹配，加盖定位精度偏差，可能导致加盖位置偏移或漏盖',
            '5002故障': '推盖数与加盖下降数不匹配，加盖动作执行异常，提示加盖机构机械故障或气压不足',
            '6001故障': '加盖数与拧盖检测数不匹配，拧盖定位环节异常，将导致拧盖位置偏差或漏拧',
            '6002故障': '拧盖下降数与旋转数不匹配，拧盖动作执行异常，提示拧盖电机故障或扭矩不足',
            '11物料推送装置故障1001': '物料推送气缸推送与收回状态异常（两者相等），可能导致物料无法正常推送，影响后续工序',
            '21物料检测装置故障2001': '物料推送数与待抓取数不匹配，提示物料检测环节存在计数偏差或物料丢失风险',
            '41填装装置检测故障4001': '放置容器数与容器上传检测数不匹配，可能存在容器定位偏差或检测传感器故障',
            '42填装装置定位故障4002': '填装定位器固定与放开状态异常（两者相等），定位功能失效，将导致填装位置偏差',
            '43填装装置填装故障4003': '物料待抓取数与实际抓取数不匹配，提示填装环节物料抓取机构异常或物料卡滞',
            '51加盖装置定位故障5001': '填装数与加盖检测数不匹配，加盖定位精度偏差，可能导致加盖位置偏移或漏盖',
            '52加盖装置加盖故障5002': '推盖数与加盖下降数不匹配，加盖动作执行异常，提示加盖机构机械故障或气压不足',
            '61拧盖装置定位故障6001': '加盖数与拧盖检测数不匹配，拧盖定位环节异常，将导致拧盖位置偏差或漏拧',
            '62拧盖装置拧盖故障6002': '拧盖下降数与旋转数不匹配，拧盖动作执行异常，提示拧盖电机故障或扭矩不足'
        };
        return descMap[modelKey] || `未找到「${modelKey}」的详细说明，建议检查对应设备运行状态`;
    }

    // ---------------------- 基础事件绑定（整合所有模块事件） ----------------------
    function bindBaseEventListeners() {
        // 1. 通用基础事件
        safeAddEvent('sidebarToggle', 'click', toggleGlobalSidebar);
        safeAddEvent('adminDropdownBtn', 'click', toggleAdminDropdown);
        safeAddEvent('close-alert-btn', 'click', () => $id('real-time-alert').classList.add('hidden'));
        safeAddEvent('close-modal-btn', 'click', closeFaultModal);
        safeAddEvent('confirm-modal-btn', 'click', closeFaultModal);
        safeAddEvent('confirm-alert-btn', 'click', closeAlertModal);

        // 点击弹窗外部关闭
        $id('fault-detail-modal').addEventListener('click', (e) => {
            if (e.target === $id('fault-detail-modal')) closeFaultModal();
        });
        $id('alert-modal').addEventListener('click', (e) => {
            if (e.target === $id('alert-modal')) closeAlertModal();
        });

        // 2. 故障日期查询模块事件
        safeAddEvent('date-confirm-btn', 'click', () => {
            const selectedDate = $id('date-picker').value;
            if (!selectedDate) {
                showAlertModal('提示', '请先选择查询日期', 'info');
                return;
            }
            $id('initial-empty-state').classList.add('hidden');
            $id('data-content').classList.remove('hidden');
            $id('date-tip').classList.remove('hidden');
            $id('last-update-container').classList.remove('hidden');
            fetchFaultData();
            hasInitiatedDataLoad = true;
        });
        safeAddEvent('line-select', 'change', () => {
            if (hasInitiatedDataLoad) fetchFaultData();
        });
        safeAddEvent('date-picker', 'change', () => {
            if (hasInitiatedDataLoad) {
                showAlertModal('日期已变更', '请点击「确认」按钮加载新日期数据', 'info');
            }
        });
        safeAddEvent('refresh-btn', 'click', fetchFaultData);
        safeAddEvent('clear-cache-btn', 'click', clearFaultCache);

        // 3. 实时监测模块事件
        safeAddEvent('start-monitor-btn', 'click', () => controlRealtimeMonitor('start'));
        safeAddEvent('stop-monitor-btn', 'click', () => controlRealtimeMonitor('stop'));
        safeAddEvent('realtime-line-select', 'change', () => {
            if (realtimeModule.isRunning) controlRealtimeMonitor('stop');
            realtimeModule.detailData = [];
            updateRealtimeDetail(null);
        });
        safeAddEvent('refresh-realtime-history', 'click', () => {
            if (realtimeModule.isRunning) fetchRealtimeData();
        });

        // 4. 系统设置模块事件（主题切换兼容）
        safeAddEvent('theme-select', 'change', (e) => {
            const theme = e.target.value;
            localStorage.setItem('theme', theme);
            applyTheme(theme);
        });
    }
</script>
</body>
</html>